I have been working with a book called "Python Programming For The Absolute Beginner", which has covered the basics well. I'm now ready to try something a bit more challenging, so I have started a little game. This will be a "fishing" game, where you have to catch fish using a harpoon.
So far I have animated the water and created a boat which can be moved left and right using keys. There is a harpoon gun on the boat which can be rotated, and the boat bobs up and down as the waves move past.
I'll be creating fish which swim past under the boat, and you have to aim your harpoon at the fish. Different fish will give more points, and there will be fish to avoid such as sharks and electric eels. You'll be able to sell your catch to get better equipment such as a better boat, faster harpoon, stun grenade etc.
I've been getting used to object-oriented programming, which is quite a new concept for me. It's a way of organising your program by splitting it up into chunks which manage themselves. So, there's an object called Boat which has code to make it move, and bob up and down. Another object is the gun, and it need to contain code which allows it to rotate and follow the boat around.
Drawing the screen in Python takes some getting used to. There's a plug-in module called Pygame which handles the graphics, but you need to do quite a bit to get it working. In Small Basic you just have to say "here's a sprite", but in Python you have to say: "Create a sprite object. Open an image. Apply the image to the surface of the sprite. Copy the sprite's surface onto the screen's surface. Tell the screen to update itself."
You can also ignore sprites altogether and just draw the images directly onto the screen myself. In the example so far I have done both. The waves are drawn onto the screen manually, as is the gunbarrel. The boat and the gun-base are Sprites. I don't know which one I prefer. I don't even know why someone would do one rather than the other. If you know, please leave a comment.
So far, I like the way it's moving. The graphics are a touch ugly. Python doesn't seem to anti-alias, so the edges are quite rough. I'll work on tarting up the bitmaps later when I have it working properly.
Image resources are here.
Download the source code here.
#wave
import pygame,math
pygame.init()
window = pygame.display.set_mode((750, 600))
pygame.display.set_caption('Wave')
screen = pygame.display.get_surface()
def loadImageFile( fileName, useColorKey = False ):
try:
image = pygame.image.load( fileName )
except pygame.error:
raise IOError from "File " + fileName + " not found."
# To speed things up, convert the images to SDL's internal format.
image = image.convert()
if useColorKey is True:
# Use the color of the pixel located at (0,0) as our color-key
colorkey = image.get_at( (0,0) )
image.set_colorkey( colorkey, pygame.RLEACCEL )
# Return the image
return image
class Wave():
"""a moving wave"""
def __init__(self,x):
self.x = x
self.surface = pygame.image.load("wave.png")
def Drawme(self):
screen.blit(self.surface, (self.x,10))
def pos(self):
return self.x
def Moveme(self):
self.x -= 3
if self.x <-740:
self.x += 1480
class Boat(pygame.sprite.Sprite):
"""a sprite that bobs"""
def __init__(self,gunbase,gunbarrel):
self.depth=0
self.gunbase = gunbase
self.gunbarrel = gunbarrel
pygame.sprite.Sprite.__init__(self)
self.image = loadImageFile("boat.bmp",True)
self.rect = self.image.get_rect()
self.rect.topleft=(350,10)
self.dir=0
def turn(self, direction):
"turn some amount"
oldCenter = self.rect.center
self.dir = direction
if direction==-1:
self.image = loadImageFile("boat1.bmp", True)
elif direction==1:
self.image = loadImageFile("boat2.bmp", True)
self.rect = self.image.get_rect()
self.rect.center = oldCenter
def Move(self,dist):
if self.rect.left+dist >0 and self.rect.right+dist<750:
self.rect.move_ip(dist,0)
self.gunbase.rect.move_ip(dist,0)
self.gunbarrel.movex(dist)
def Bob(self,wave1,wave2):
x = wave1.pos()
if x > self.rect.center[0]:
x = wave2.pos()
olddepth = self.depth
diff = math.fabs((x - self.rect.center[0]-40)%750)
self.depth= (math.fabs(375-diff))/375
self.rect.top = (self.depth*20+5)
self.gunbase.rect.top = (self.rect.top+50)
self.gunbarrel.setY(self.rect.top+70)
if self.depth <(olddepth) and self.dir!=-1:
#rotate up
self.turn(-1)
elif self.depth>(olddepth)and self.dir!=1:
#rotate down
self.turn(1)
class Gunbase(pygame.sprite.Sprite):
"""An attached gunbase"""
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = loadImageFile("gunbase.bmp",True)
self.rect = self.image.get_rect()
self.rect.topleft=(400,100)
class Turret:
def __init__(self):
self.x = 413
self.y = 80
self.image = pygame.image.load("gun.bmp")
self.imageblack = pygame.image.load("gun.bmp")
image = self.image
self.baseImage = self.image
self.dir = 0
image.set_colorkey(image.get_at((0,0)))
def turn(self, amount):
self.dir += amount
self.image = pygame.transform.rotate(self.baseImage, self.dir)
self.rect = self.image.get_rect()
def movex (self, dist):
self.x +=dist
def setY(self,y):
self.y = y
def draw (self):
screen.blit(self.image, [(self.x - self.image.get_rect().width/2),(self.y - self.image.get_rect().height/2)])
def drawblack (self):
screen.blit(self.imageblack, [(self.x - self.image.get_rect().width/2),(self.y - self.image.get_rect().height/2)])
def turrettipx(self):
return math.floor(self.x + (math.sin(math.radians(self.dir))*20))
def turrettipy(self):
return math.floor(self.y + (math.cos(math.radians(self.dir))*20))
def main():
done=False
clock = pygame.time.Clock()
mainscreen = pygame.Rect(0,65,750,535)
topbar = pygame.Rect(0,0,750,65)
wave1 = Wave(0)
wave2 = Wave(740)
gunbarrel = Turret()
gunbase = Gunbase()
boat = Boat(gunbase,gunbarrel)
while done==False:
#movewave
wave1.Moveme()
wave2.Moveme()
#draw wave
screen.fill([168,254,255],mainscreen)
screen.fill([255,255,255],topbar)
wave1.Drawme()
wave2.Drawme()
dist=0
for event in pygame.event.get(): # User did something
if event.type == pygame.QUIT: # If user clicked close
done=True # Flag that we are done so we exit this loop
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
dist=3
elif keys[pygame.K_LEFT]:
dist=-3
if keys[pygame.K_a]:
gunbarrel.turn(-5)
#move boat
boat.Move(dist)
#bob boat
boat.Bob(wave1,wave2)
boatsprite=pygame.sprite.RenderPlain(boat)
boatsprite.update()
boatsprite.draw(screen)
gunbasesprite=pygame.sprite.RenderPlain(gunbase)
gunbasesprite.update()
gunbasesprite.draw(screen)
gunbarrel.draw()
#draw turrent tip
#pygame.draw.circle(screen,[0,0,0],[gunbarrel.turrettipx(),gunbarrel.turrettipy()],5,0)
# Go ahead and update the screen with what we've drawn.
# This MUST happen after all the other drawing commands.
pygame.display.flip()
clock.tick(80)
pygame.quit()
main()
No comments:
Post a Comment