Making an image shoot
#2 Members - Reputation: 100
Posted 05 February 2011 - 02:22 PM
import pygame
class Tank:
def __init__(self):
self.tank = pygame.image.load("tank.png")
self.x = -200
self.y = 20
def draw(self, surface):
surface.blit(self.tank, (self.x, self.y))
class Lvl_1:
def __init__(self):
self.floor = pygame.image.load("floor.png")
def draw(self, surface):
surface.blit(self.floor, (0, 0))
class Enemy_tank:
def __init__(self):
self.enemy_tank = pygame.image.load("enemy_tank.png")
def draw(self, surface):
surface.blit(self.enemy_tank, (100, -40))
pygame.init()
background_color = (0,0,0)
(width, height) = (640, 480)
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('Game Window')
clock = pygame.time.Clock()
tank = Tank()
lvl_1 = Lvl_1()
enemy_tank = Enemy_tank()
pygame.key.set_repeat(1,50)
running = True
while running:
screen.fill (background_color)
tank.draw(screen)
lvl_1.draw(screen)
enemy_tank.draw(screen)
pygame.display.flip()
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
tank.x += 5
if event.key == pygame.K_LEFT:
tank.x -= 5
#3 Members - Reputation: 122
Posted 05 February 2011 - 03:09 PM
Does pygame keep track of resource management? If you call pygame.image.load twice for the same image, will it be loaded again (bad) or will you get the same image (good)? If the former is the case, you'll need to avoid duplicate loading yourself, you don't want a new image to be created for each Bullet object.
And your Tank needs a Shoot() function which creates a new Bullet, which is then added to some kind of list so you can keep track of it (e.g. call Update()).
This is a pretty general answer since your question is rather vague, too. Should give you a general idea of how you can do it. (There are many ways of doing it.) If you need more specific information, ask more specific questions.
So long,
Mr. Wonko
#4 Members - Reputation: 125
Posted 05 February 2011 - 03:26 PM
Here is a nice link to some python game programming examples.
I used these when I was first learning.
http://eli.thegreenplace.net/2008/12/13/writing-a-game-in-python-with-pygame-part-i/
The biggest thing you should figure out is to learn to think "how do I do something"
I learned a while ago, that when i wanted something to happen in a game, I would write down everything that I wanted to happen. For example:
* I want a bullet to shoot from my tank
* It will shoot to the right
* It's speed will be 10 pixels per frame
* Gravity will not effect it
* When it hits something, the bullet will go away.
* If it does not hit something, and goes off screen, the bullet will go away.
* There can only be 1 bullet on screen at a time.
You will probably need to give the bullet a boolean for being on screen.
And maybe another boolean for on hit.
Now in your main loop, if space bar is press, you can have it activate a function in the bullet class to activate the on screen flag, and change its x and y position to be near your tank.
You will want to make it so that it will only do that if the on screen flag is set to false.
Also in the main loop, right behind the draw function for the bullet, you can have an update position function, That will increase it's x position 10 to the right.
After that call, you can have another function to check its position compared to the end of the screen and see if it will collide with another tank. If the check is true, then you can change the on hit flag to true. So now when the draw function is called, the on hit flag will show an explosion picture instead of a bullet picture. After the picture is shown, you change the on hit and on screen flag to false.
It is pretty rudimentary. But take a look at that link i provided. It is pretty nice.
Good luck!
#6 Members - Reputation: 100
Posted 05 February 2011 - 08:37 PM
class Bullet:
def __init__(self):
self.bullet = pygame.image.load("tank_bullet.png")
self.speed = 10
#7 Banned - Reputation: 34
Posted 05 February 2011 - 11:54 PM
This is the partially completed bullet class is there some special way to draw the bullet since I don't want to draw it until the space bar is pressed?
class Bullet: def __init__(self): self.bullet = pygame.image.load("tank_bullet.png") self.speed = 10
Something like:
1. Wait for the spacebar keydown event
a.Get position of the person or ship
b. From that point, have it travel as you want
c. use a bool to determine if it has hit something.
#8 Members - Reputation: 100
Posted 06 February 2011 - 11:37 AM
class Bullet:
def __init__(self):
self.bullet = pygame.image.load("tank_bullet.png")
self.speed = 10
self.y = tank.y
self.x = tank.x
def draw(self, surface):
if event.key == pygame.K_SPACE:
surface.blit(self.bullet, (self.x, self.y))
#9 Members - Reputation: 560
Posted 06 February 2011 - 12:37 PM
I'm having trouble getting it to shoot I'm not completely sure if I'm doing it right can someone tell me if I am and if not what am I doing wrong? This is what I have so far.
class Bullet: def __init__(self): self.bullet = pygame.image.load("tank_bullet.png") self.speed = 10 self.y = tank.y self.x = tank.x def draw(self, surface): if event.key == pygame.K_SPACE: surface.blit(self.bullet, (self.x, self.y))
I've been following this thread, and your previous. To be honest, I don't think you have what it takes at this point in time, to accomplish what you are trying to do. You need to understand what is going on with your code, and not just blindly copy peoples suggestions here. You will not get anywhere, and eventually those who are helping will grow tired of your neediness. I'm sorry it just needs to be said. With that out of the way, let's look at POSSIBLE solutions.
You were given a *great* leg up by Enders, who went though the process of design, rather than just providing an answer. You ran with it and got stuck. These things happen, don't let it get you down. Fl4sh provided a general solution, and you tried again, resulting in your current code. Looking at that, your saying that if your drawing, and the space key is pressed, then blit the surface. Does this sound like what you want to have happen? Should the bullet itself be firing itself?
Let's move back a sec and look at the tank class, it has a method to draw itself, but that is it. doesn't a tank do more? lets add 2 methods to tank. Fire, and update. Fire is where we will handle the creating of a bullet, and update will be a method that will allow us to handle updates to the tank. Once again i've no experience with python, so I have no idea if this syntax is correct, but hopefully you will understand enough to make it work
def update(time) : // the time variable allows us to watch time elapsed for things like reloading ammo, special moves, etc, but if youd don't need it it's fine to leave it out for now if event.Key == pygame.K_SPACE: self.fire()sorry for the c style comments, hope you can see what's going on there. No code, just a design template for you to work with. so the tank will now fire if the space key is down during it's update.
def fire(): // create a bullet //set the bullets position to the tanks position // give the bullet a direction // add the bullet to a list of bulletsSo the fire method will create, and initialize the bullet object so it is ready to go
def update(time) : self.x += self.xdirection *self.speed * time self.y += self.ydirection * self.speed * timeThis update method will fit in the bullet class. basically every update, it moves a distance along it's direction, which is it's speed * time elapsed.
Now we have a method for creating a bullet, a method for updating it, and a method to update the tank. your main loops will now look something like
while running
//update game state
tank.update(time) // you will need to get how much time has elapsed since last frame
enemy_tank.update(time)
foreach(bullet in bulletlist)
{
bullet.update()
}
// gamestate is updated, so lets draw it
tank.draw(screen)
lvl_1.draw(screen)
enemy_tank.draw(screen)
pygame.display.flip()
clock.tick(30)
#10 Members - Reputation: 100
Posted 06 February 2011 - 05:32 PM
class Tank:
def __init__(self):
self.tank = pygame.image.load("tank.png")
self.x = -200
self.y = 20
def draw(self, surface):
surface.blit(self.tank, (self.x, self.y))
def update(time):
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
self.fire()
class Bullet:
def fire():
self.bullet = pygame.image.load("tank_bullet.png")
self.y = tank.y
self.x = tank.x
self.speed = 10
right = self.x + 5
def update(time):
self.x += self.x, right * self.speed * 30
self.y += self.y, right * self.speed * 30
#13 Members - Reputation: 100
Posted 07 February 2011 - 02:16 PM
class Tank:
def __init__(self):
self.tank = pygame.image.load("tank.png")
self.x = -200
self.y = 20
def draw(self, surface):
surface.blit(self.tank, (self.x, self.y))
def update(time):
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
self.fire()
def fire():
self.bullet = pygame.image.load("tank_bullet.png")
self.y = tank.y
self.x = tank.x
self.speed = 10
right = self.x + 5
def update(time):
self.x += self.x, right * self.speed * 30
self.y += self.y, right * self.speed * 30
#14 Banned - Reputation: 34
Posted 07 February 2011 - 02:34 PM
You have to understand what's going on with the code... at-least to some degree.
#15 Members - Reputation: 330
Posted 07 February 2011 - 02:34 PM
Take a deep breath. Plan things out in pseudo-code first. It'll make it so much easier.
Class Tank Methods: __init__ Draw Update Fire Class Bullet Methods: __init__ Draw Update
Of course, then there is the matter of how this all plugs into the game. How do you keep track of the bullets the tank fires? (Maybe with a list? A vector? Array?). Then you need to call Update() in your game's Update method, and Draw in your Draw method and so on. Good luck!
~ Gabe
"I don't mean to rush you but you are keeping two civilizations waiting!"
~ Cavil, BSG.
"If it's really important to you that other people follow your True Brace Style, it just indicates you're inexperienced. Go find something productive to do."
~ Bregma
"Well, you're not alone.
There's a club for people like that. It's called Everybody and we meet at the bar."
~ Antheus
#16 Members - Reputation: 100
Posted 07 February 2011 - 04:13 PM
class Tank:
def __init__(self):
self.tank = pygame.image.load("tank.png")
self.x = -200
self.y = 20
def draw(self, surface):
surface.blit(self.tank, (self.x, self.y))
def update():
self.tank.Update()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
self.fire()
def fire():
if self.fire():
__init__(bullet)
class Bullet:
def __init__(self):
self.bullet = pygame.image.load("tank_bullet.png")
self.y = tank.y
self.x = tank.x
self.speed = 10
right = self.x + 5
def draw(self, surface):
surface.blit(self.x, self.y)
def update():
self.bullet.Update()
self.x += self.x, right * self.speed * 30
self.y += self.y, right * self.speed * 30
I am also starting to think there could be a problem in the main loop:
pygame.init()
background_color = (0,0,0)
(width, height) = (640, 480)
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('Game Window')
clock = pygame.time.Clock()
tank = Tank()
lvl_1 = Lvl_1()
bullet = Bullet()
enemy_tank = Enemy_tank()
pygame.key.set_repeat(1,50)
running = True
while running:
screen.fill (background_color)
tank.draw(screen)
lvl_1.draw(screen)
enemy_tank.draw(screen)
pygame.display.flip()
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
tank.x += 5
if event.key == pygame.K_LEFT:
tank.x -= 5
#17 Members - Reputation: 560
Posted 07 February 2011 - 06:53 PM
Ok I still don't fully understand the fire() but I tried, it still doesn't work but is this closer?
class Tank: def __init__(self): self.tank = pygame.image.load("tank.png") self.x = -200 self.y = 20 self.firecountdown=0 # this will make sure you only fire once in a while, not every key repeat def draw(self, surface): surface.blit(self.tank, (self.x, self.y)) def update(dt): # this dt is the same one passed when update is called and represents the number of milliseconds elapsed since last frame if(self.firecountdown > 0) # if we are still reloading, self.firecountdown-= dt #lower the firecountdown by time elapsed. def fire(): if(self.firecountdown <=0) : # only fire if we are not reloading bullet.x = tank.x bullet.y = tank.y bullet.speed = 10 self.firecountdown = 1000 # since we fired, we need to reload. lets reload for 1000ms class Bullet: def __init__(self): self.bullet = pygame.image.load("tank_bullet.png") self.y = tank.y self.x = tank.x self.speed = 0 self.forwardx = 1 self.forwardy = 0 def draw(self, surface): surface.blit(self.x, self.y) def update(dt): self.x += self.forwardx * self.speed/1000 # new x coord = old + forwardx * speed * time self.y += self.forwardy * self.speed/1000 # new y coord is similar
I am also starting to think there could be a problem in the main loop:pygame.init() background_color = (0,0,0) (width, height) = (640, 480) screen = pygame.display.set_mode((width, height)) pygame.display.set_caption('Game Window') clock = pygame.time.Clock() tank = Tank() lvl_1 = Lvl_1() bullet = Bullet() enemy_tank = Enemy_tank() pygame.key.set_repeat(1,50) running = True while running: # this will store the time since last frame in the variable dt for use. dt =clock.tick(30) # Update the game state, including all entities/bullets/etc tank.update(dt) enemy_tank.update(dt) bullet.update(dt) # the game state is up to date, so lets draw it screen.fill (background_color) lvl_1.draw(screen) tank.draw(screen) bullet.draw(screen) enemy_tank.draw(screen) pygame.display.flip() for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.KEYDOWN: if event.key == pygame.K_RIGHT: tank.x += 5 if event.key == pygame.K_LEFT: tank.x -= 5 # added detection for the spacebar, making tank fire bullet if event.key == pygame.K_SPACE: tank.fire()
I know i'm beating a dead horse here, but what is tank.self.fire()? you really... really... really need to understand the fundamentals of programming, python, and logic better before you attempt to make a game. I've edited your source as best as i can(Still don't know python, but 20 minutes on google helped, and i really should learn it anyway, for my own use at some point) and commented as much as I deemed necessary. Rather than starting a new thread when you've got this working, keep posting to this one so as not to clutter the forums. Hopefully if someone else is stuck at the same point you are, they will learn from this as well.
#18 Members - Reputation: 100
Posted 07 February 2011 - 07:20 PM
Traceback (most recent call last):
File "/home/bolt/Python/game.py", line 71, in <module>
tank.update(dt)
AttributeError: Tank instance has no attribute 'update'
#19 Members - Reputation: 560
Posted 07 February 2011 - 08:20 PM
Ok I have made the changes and everything is good except there is an error with the tank.update(dt), enemy_tank.update(dt), and bullet.update(dt) and I have tried some changes and I googled it but I still can't figure it out do you know how? This is the error:
Traceback (most recent call last):
File "/home/bolt/Python/game.py", line 71, in <module>
tank.update(dt)
AttributeError: Tank instance has no attribute 'update'
hmmm... Can you repost the entire source file(copy and paste prefered) as it is now so I can have a looksee?
#20 Members - Reputation: 100
Posted 08 February 2011 - 02:08 PM
import pygame
class Tank:
def __init__(self):
self.tank = pygame.image.load("tank.png")
self.x = -200
self.y = 20
self.firecountdown=0 # this will make sure you only fire once in a while, not every key repeat
def draw(self, surface):
surface.blit(self.tank, (self.x, self.y))
def update(dt):
# this dt is the same one passed when update is called and represents the number of milliseconds elapsed since last frame
if(self.firecountdown > 0):
self.firecountdown-= dt #lower the firecountdown by time elapsed.
def fire():
if(self.firecountdown <=0) : # only fire if we are not reloading
bullet.x = tank.x
bullet.y = tank.y
bullet.speed = 10
self.firecountdown = 1000 # since we fired, we need to reload. lets reload for 1000ms
class Bullet:
def __init__(self):
self.bullet = pygame.image.load("tank_bullet.png")
self.y = tank.y
self.x = tank.x
self.speed = 0
self.forwardx = 1
self.forwardy = 0
def draw(self, surface):
surface.blit(self.x, self.y)
def update(dt):
self.x += self.forwardx * self.speed/1000 # new x coord = old + forwardx * speed * time
self.y += self.forwardy * self.speed/1000 # new y coord is similar
class Lvl_1:
def __init__(self):
self.floor = pygame.image.load("floor.png")
def draw(self, surface):
surface.blit(self.floor, (0, 0))
class Enemy_tank:
def __init__(self):
self.enemy_tank = pygame.image.load("enemy_tank.png")
def draw(self, surface):
surface.blit(self.enemy_tank, (220, -40))
pygame.init()
background_color = (0,0,0)
(width, height) = (640, 480)
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('Game Window')
clock = pygame.time.Clock()
tank = Tank()
lvl_1 = Lvl_1()
bullet = Bullet()
enemy_tank = Enemy_tank()
pygame.key.set_repeat(1,50)
running = True
tank.update(dt)
enemy_tank.update(dt)
bullet.update(dt)
# the game state is up to date, so lets draw it
screen.fill (background_color)
lvl_1.draw(screen)
tank.draw(screen)
bullet.draw(screen)
enemy_tank.draw(screen)
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
tank.x += 5
if event.key == pygame.K_LEFT:
tank.x -= 5
# added detection for the spacebar, making tank fire bullet
if event.key == pygame.K_SPACE:
tank.fire()






