I've been suck on my Flappy Bird clone. If you don't know the game, there is an animation that happens when the bird fly up.
Here is a general idea of how I tried to do an animation:
self.x and self.y refer to the position of the photo
Here is my code:
def move_up_animation(self):
#list of bird photos to animate
animation_list = ['1.tiff','2.tiff','3.tiff','4.tiff','5.tiff']
for i in range(len(animation_list)):
if self.y - 1 > 0: # checks if the bird is within the frame
self.y = self.y - 1 #changes the bird's, allowing the bird to fly up
self.image = pygame.image.load(animation[i])
self.display_image()
I tried time.sleep(1) but it doesn't work.
I have no idea how this code works:
for i in range(5):
print(i)
time.sleep(1)
"I have no idea how this code works":
for i in range(5):
print(i)
time.sleep(1)"
It works like that: for will see if it's a true or false variable I on the range (0, 5), not 5. If it is true will run the print command.
time.sleep I don't know how it works.
To move the bird you need to add and decrease the y axis, for both flying and gravity. I hope you know to do do it (like pressing space it flies, no pressing it falls).
Instead of using for you can use if.
if K_SPACE:
y -= 12
It will make the y-axis of the bird increase by 12. I hope that will be like the original jump game. To make it smooth you can use .tick() module inside the for, but I think it is really unnecessary.
Related
i'm trying to code a small grid game, but i'm having trouble with coding piece movements.
I have a small 4x4 rgb pixels grid, initialized as np.zeros(4,4,3), full black. An update method to refresh objects position and free cells, a reset method, and a simple show function that uses cv2 to show the grid from a pixel matrix.
class Grid():
def __init__(self):
self.cells = np.zeros((SIZE, SIZE, 3), dtype=np.uint8)
self.free_cells = []
def update(self, c, l):
self.reset() #clear cells and free cells list
self.cells[c.x][c.y] = COIN_COL #set coin position
for i in range(len(l.coords)): #set L posiion
self.cells[l.coords[i][0]][l.coords[i][1]] = L_COL
for i in range(len(self.cells)): #calculate free cells
for j in range(len(self.cells)):
if np.amax(self.cells[i][j]) == 0:
self.free_cells.append((i, j))
def reset(self):
self.cells = np.zeros((SIZE, SIZE, 3), dtype=np.uint8)
self.free_cells = []
def show(self):
img = Image.fromarray(self.cells, "RGB")
img = img.resize((200,200))
cv2.imshow('img', np.array(img))
cv2.waitKey(0)
on the grid there are 2 pieces, an L-shaped one 3x2, and a coin 1x1.
they both have colors and coordinates
SIZE = 4
COIN_COL = (255,255,255)
L_COL = (0,0,255)
C_COORDS = np.array((0,0), dtype=np.uint8) #coin starting position
L_COORDS = np.array(((1,1),(2,1),(3,1),(3,2)), dtype=np.uint8) #L starting position
class Coin():
def __init__(self, coords):
self.x = coords[0]
self.y = coords[1]
class LShape():
def __init__(self, coords):
self.coords = coords
each piece can rotate, translate and move whenever he wants as long as it stays inside the grid, and does not overlap with other pieces.
moving the coin is straightforward: check empty cells, choose one, update coin coordinates, update grid.
Moving the L, doesn't look that simple. How can i check every possible legal move of such a piece? (there could be more than 1 coin on the grid). i started by calculating the empty cells, so that i have a layout of the free space, and i'm trying to come up with an algorithm to highlight legal moves by first removing isolated free cells (1x1), than removing isolated couples (2x1), and so on, but i got stuck halfway through.
I was also thinking about making a list of every possible position on an empty grid, and removing positions from the list if they require an occupied cell, but that doesn't seems elegant nor optimal.
Any idea on how to approach the problem?
the endeavor is to draw clusters of rects [bubbles] moving up the screen at varying rates of speed. i've hit a roadblock when it comes to rendering the moving rects.
the way i've gone about it thus far is to populate a list with class instances of my Bubble class. from there i've iterated through the list of instances and called their blow_bubble method, effectively drawing each bubble at a different location on the screen and initializing each with its own value for its speed of movement. these bubbles are then appended to a separate list entitled "drawn", to signify that they have indeed been drawn (though not rendered).
the next part is where it gets bumpy.
i have a while loop that accepts the length of the drawn list being greater than zero as its condition for running. as per the form in this article: http://programarcadegames.com/index.php?chapter=introduction_to_animation
the screen surface is set to fill at the beginning of the loop and at the end of it i've updated the screen surface via pygame.display.flip(). in the middle of the while loop i'm iterating through class instances in the drawn list and decrementing the attribute that represents their y value by the instance's attributed rate of movement.
somehow this doesn't work.
i've checked to make sure the y value is actually decrementing; in a print statement the output is what would be expected: the y value descends into the negative numbers. yet the rects remain drawn statically.
as always, any insights are greatly appreciated.
#colors, screen, clock, etc defined above but omitted
pygame.init()
class Bubble():
def __init__(self, screenheight, screenwidth):
self.w = self.h = 0
self.x, self.y = 0, 0
self.moverate = 0
def reset_bubble(self):
self.w = self.h = random.randrange(2, int(screenwidth*1/4))
self.x = random.randrange(0, (screenwidth-self.w))
self.y = screenheight-self.w
self.moverate = 1
def blow_bubble(self):
self.reset_bubble()
pygame.draw.rect(screen, WHITE, (self.x, self.y, self.w, self.h), 10)
bubbles = []
drawn = []
i = 0
for i in range(10): #creates list of bubble objects
bubble = Bubble(screenheight, screenwidth)
bubbles.append(bubble)
for i in range(len(bubbles)): #draws bubbles without rendering them
bubbles[i].blow_bubble()
drawn.append(bubbles[i]) #appends objects to a new list (drawn)
while len(drawn) > 0:
screen.fill((BLACK))
drawn[i].y -= drawn[i].moverate #moves the bubble up the screen
pygame.display.flip() #updates the screen
if i >= 0: #counts up til len(drawn) then counts down [then up again]
i+=1 #to make sure we move every bubble a little each iteration
if i ==len(drawn):
i-= 1
clock.tick(FPS)
pygame.quit()
Unless I'm very much mistaken about how pygame works, you've misunderstood how it works. For oygamr to work it needs a 'render loop', a loop of code in which you repeatedly move the object, draw it with something like pygame.draw.rect, and then flip the display with pygame.display.flip. You keep doing this until you're done animating.
So, you need to make a bunch of changes.
your 'blow bubble' function needs to not reset the position of the bubble, just increment its position and call pygame.draw.rect
you don't need a 'dawn' list, just the first bubble list. Inside your while loop, you need to iterate through the bubble list calling 'blow bubble' on each.
you need to move the 'pygame.display.flip' inside the while loop, but after all the bubbles have been blown.
Your index out of range error is because I is not magically reset after the for loop exits, it leaves I as whatever it was when the for loop finished.
I'm trying to create an overlay using mini_magick (Ruby wrapper for imagemagick) similar to the example below:
I know how to draw a rectangle, and I know how to rotate, but I can't wrap my head around the coordinate system once the rotation has been applied.
So I wrote the following:
x = original_icon.width / 2
y = 0 # or should it be -10 so it's off the canvas?
width = 100
height = 20
result = original_icon.combine_options do |c|
c.fill('#FF0000')
c.draw "rotate -45 rectangle #{x},#{y},#{width},#{height}"
end
However, things get odd fast after the rotate -45. It seems positioning has completely gone out the window.
Is there another way to achieve this?
I am making a drag-and-drop game with Gosu - Ruby and need to know how to get the computer to save a sprite's x and y coordinates. This is so that I can check if the user dragged the sprite to the correct spot.
Basically, you have to add the #x and #y coordinates into a Sprite class, and call that sprite from your window class. So it'll look something like this:
class Player
attr_accessor :x, :y #this will allow you to both read x,y and write to (save) x, y
def initialize x, y
#tiles = Image.new(...) #load your images for your sprite
#x = x
#y = y
end
(...other methodds...)
end
then in your GameWindow class's #update, you do whatever to the #x and #y, here:
class GameWindow < Gosu::Window
def initialize
....window init code....
#sprite = Player.new(width/2, height/2)
...other vars...
end
def update
#this is where your game physics will go, and where you will store your x and y coords for the sprite
#sprite.y+= 1
#sprite.x+= 1
end
end
Obviously this is an approximation just to give you an idea. Don't copy paste this directly cuz it won't work :P
i am working with Shoes in Ruby. I could not find a method to plot individual pixels in the shoes window.... Can anyone help me??
:)
I don't think it's possible. See Shoes GUI toolkit per pixel manipulation possible?
I think the closest you can get is a 2x2 square:
Shoes.app do
click{|b, x, y|
rect(x,y,1,1) if b == 1
}
end
Or a 2x1 line:
Shoes.app do
click{|b, x, y|
line(x,y,x+1,y) if b == 1
}
end
That means that you can do something like that if you want to draw a pixel at x,y location, with a particular color assuming you know the background color:
def point(x,y,color, bg_color)
stroke color
line x,y,x,y+1
stroke bg_color
line x,y+1,x+1,y+1
end
Shoes.app do
background white
point 40,40,blue,white
end
:)
Of course for drawing pixels densely it is useless but in some application can be useful.