Return to Snippet

Revision: 3025
at May 26, 2007 05:48 by avinashv


Updated Code
# spaceship shooter test
#
# Copyright (c) 2007, Avinash Vora
# http://www.avinashv.net
#
# Source code is protected by the GNU GPL
#
# May 26
# - added randomly generated enemies
# - added engine class
# May 25
# - added maximum ship speed
# - added anti-aliasing toggle
# - changed friction from 0.0075 to 0.01
# - implemented bullets and physics
# - fully object-oriented code
# May 24
# - added FPS read-out
# - implemented ship and physics

import pygame, math, sys, random
from pygame.locals import *

black = 0, 0, 0
white = 255, 255, 255
red = 255, 0, 0
green = 0, 255, 0

d2p = lambda x1, y1, x2, y2: math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)

class engine:
	def __init__(self, width, height):		
		self.size = self.width, self.height = width, height
		self.running = True
		self.show_fps = False
		self.aaline = False
		
		self.enemies = []
		self.ships = []
		
		# state of keypresses
		self.right_pressed, self.left_pressed, self.up_pressed = False, False, False
		self.firing = False
		
		pygame.init()
		
		self.window = pygame.display.set_mode(self.size)
		self.window.fill(black)
	
	def global_draw(self):
		for ship in self.ships:
			ship.draw()
			for bullet in ship.bullets:
				bullet.draw()
			
		for enemy in self.enemies:
			enemy.draw()
	
	def global_physics(self):
		# apply physics to every ship and bullet
		for ship in self.ships:
			ship.physics()
			
			for bullet in ship.bullets:
				bullet.physics()
				
				# check boundaries and destroy bullet if outside
				if (bullet.x > self.width) or (bullet.x < 0) or (bullet.y > self.height) or (bullet.y < 0):
					ship.bullets.remove(bullet)
					continue
				
				# destroy bullets if they are older than 1000 ms
				if bullet.death <= pygame.time.get_ticks():
					ship.bullets.remove(bullet)
					continue
				
				# check for collision
				for enemy in self.enemies:
					if d2p(bullet.x, bullet.y, enemy.x, enemy.y) < (bullet.radius + enemy.radius):
						enemy.health = enemy.health - bullet.strength
						ship.bullets.remove(bullet)
					if enemy.health <= 0:		
						self.enemies.remove(enemy)

class bullet_class:
	def __init__(self, engine, parent):
		self.engine = engine
		self.parent = parent
		self.x_comp, self.y_comp = 0, 0
		self.x, self.y = self.parent.x, self.parent.y
		self.heading = self.parent.heading
		self.facing = self.parent.facing
		self.speed = 4.5
		self.radius = 4
		self.decay = 1000
		self.death = pygame.time.get_ticks() + self.decay
		self.strength = 3
		
		# calculate resultant x and y components
		self.x_comp = self.parent.speed * math.sin(self.heading) + self.speed * math.sin(self.facing)
		self.y_comp = self.parent.speed * math.cos(self.heading) + self.speed * math.cos(self.facing)
		
		# determine resultant speed
		self.speed= math.sqrt(self.x_comp ** 2 + self.y_comp ** 2)
		
		# calculate resultant heading
		if self.y_comp >= 0:
			self.heading = math.atan(self.x_comp / self.y_comp)
		elif self.y_comp < 0:
			self.heading = math.atan(self.x_comp / self.y_comp) + math.pi
	
	def draw(self):
		if self.engine.aaline:
			pygame.draw.circle(self.engine.window, green, (int(self.x), int(self.y)), self.radius, 1)
		else:
			pygame.draw.circle(self.engine.window, green, (int(self.x), int(self.y)), self.radius, 2)

	def physics(self):
		# adjust (x, y) according to speed
		self.x = self.x + self.speed * math.sin(self.heading)
		self.y = self.y - self.speed * math.cos(self.heading)

class enemy_class:
	def __init__(self, engine, health):
		self.engine = engine
		self.x, self.y = random.randint(1, self.engine.width), random.randint(1, self.engine.height)
		self.health = health
		self.radius = self.health
	
	def draw(self):
		if self.engine.aaline:
			pygame.draw.circle(self.engine.window, white, (int(self.x), int(self.y)), self.radius, 1)
		else:
			pygame.draw.circle(self.engine.window, white, (int(self.x), int(self.y)), self.radius, 2)

class spaceship_class:
	def __init__(self, engine):
		self.engine = engine
		self.accel = 0.06
		self.friction = 0.01
		self.max_speed = 4
		self.rotation_rate = 5
		self.x, self.y = self.engine.width / 2, self.engine.height / 2
		self.x_comp, self.y_comp = 0, 0
		self.facing = 0
		self.heading = 0
		self.speed = 0
		self.radius = 10
		self.bullet_delay = 200
		self.last_bullet_time = 0
		
		# holds all the bullets created by this instance
		self.bullets = []
	
	def draw(self):
		# calculate vertices of the ship
		vertices = [
			(self.x + self.radius * math.sin(self.facing), self.y - self.radius * math.cos(self.facing)),
			(self.x + self.radius * math.sin(self.facing + 2 * math.pi / 3), self.y - self.radius * math.cos(self.facing + 2 * math.pi / 3)),
			(self.x + self.radius * math.sin(self.facing + 4 * math.pi / 3), self.y - self.radius * math.cos(self.facing + 4 * math.pi / 3))
		]
		
		# draw lines with the back of the ship as red (anti-aliased if needed)
		if self.engine.aaline:
			pygame.draw.aaline(self.engine.window, white, vertices[0], vertices[1])
			pygame.draw.aaline(self.engine.window, white, vertices[2], vertices[0])
			pygame.draw.aaline(self.engine.window, red, vertices[1], vertices[2])
		else:
			pygame.draw.line(self.engine.window, white, vertices[0], vertices[1], 2)
			pygame.draw.line(self.engine.window, white, vertices[2], vertices[0], 2)
			pygame.draw.line(self.engine.window, red, vertices[1], vertices[2], 2)

	def physics(self):
		if self.engine.right_pressed:
			# determine new direction
			self.facing = self.facing + (self.rotation_rate * math.pi) / 180
			
		if self.engine.left_pressed:
			# determine new direction
			self.facing = self.facing - (self.rotation_rate * math.pi) / 180
		
		if self.engine.up_pressed:
			# determine resultant x and y components
			self.x_comp = self.speed * math.sin(self.heading) + self.accel * math.sin(self.facing)
			self.y_comp = self.speed * math.cos(self.heading) + self.accel * math.cos(self.facing)
			
			# determine resultant speed
			if self.speed < self.max_speed:
				self.speed = math.sqrt(self.x_comp ** 2 + self.y_comp ** 2)
			else:
				self.speed = self.max_speed
			
			# calculate resultant heading
			if self.y_comp >= 0:
				self.heading = math.atan(self.x_comp / self.y_comp)
			elif self.y_comp < 0:
				self.heading = math.atan(self.x_comp / self.y_comp) + math.pi
		
		# create new bullet
		if self.engine.firing:
			if pygame.time.get_ticks() >= (self.last_bullet_time + self.bullet_delay):
				self.bullets.append(bullet_class(self.engine, self))
				self.last_bullet_time = pygame.time.get_ticks()
		
		# adjust speed for friction
		if self.speed > 0: self.speed = self.speed - self.friction
		
		# adjust (x, y) according to speed
		self.x = self.x + self.speed * math.sin(self.heading)
		self.y = self.y - self.speed * math.cos(self.heading)
		
		# check boundaries
		if self.x > self.engine.width: self.x = 0
		if self.x < 0: self.x = self.engine.width
		if self.y > self.engine.height: self.y = 0
		if self.y < 0: self.y = self.engine.height

if __name__ == '__main__':
	if not pygame.font:  print 'Fonts disabled!'
	if not pygame.mixer: print 'Sound disabled!'
	
	game = engine(640, 480)
	clock = pygame.time.Clock()
	
	pygame.display.set_caption('shooter test')
	
	game.ships.append(spaceship_class(game))
	
	for item in range(1, random.randint(5, 15)): game.enemies.append(enemy_class(game, random.randint(5, 15)))
	
	while game.running:
		# limit fps to 60
		clock.tick(60)
		
		# clear screen
		game.window.fill(black)
		
		# show fps
		if pygame.font and game.show_fps:
			font = pygame.font.Font(None, 16)
			text = font.render('fps ' + str(int(clock.get_fps())), 1, (150, 150, 150))
			text_position = text.get_rect(centerx = game.width / 2)
			game.window.blit(text, text_position)
		
		# handle physics and drawing
		game.global_physics()
		game.global_draw()
		
		# flip the screen
		pygame.display.update()
		
		# handle input
		for event in pygame.event.get():
			if event.type == QUIT:
				running = False
			
			# key down
			elif event.type == KEYDOWN:
				if event.key == K_ESCAPE:
					game.running = False
				elif event.key == K_RIGHT:
					game.right_pressed = True
				elif event.key == K_LEFT:
					game.left_pressed = True
				elif event.key == K_UP:
					game.up_pressed = True
				elif event.key == K_z:
					game.firing = True
				elif event.key == K_f:
					game.show_fps = not game.show_fps
				elif event.key == K_a:
					game.aaline = not game.aaline
			
			# key up
			elif event.type == KEYUP:
				if event.key == K_RIGHT:
					game.right_pressed = False
				elif event.key == K_LEFT:
					game.left_pressed = False
				elif event.key == K_UP:
					game.up_pressed = False
				elif event.key == K_z:
					game.firing = False

Revision: 3024
at May 26, 2007 05:28 by avinashv


Updated Code
# spaceship shooter test
#
# Copyright (c) 2007, Avinash Vora
# http://www.avinashv.net
#
# Source code is protected by the GNU GPL
#
# May 26
# - added randomly generated enemies
# - added engine class
# May 25
# - added maximum ship speed
# - added anti-aliasing toggle
# - changed friction from 0.0075 to 0.01
# - implemented bullets and physics
# - fully object-oriented code
# May 24
# - added FPS read-out
# - implemented ship and physics

import pygame, math, sys, random
from pygame.locals import *

black = 0, 0, 0
white = 255, 255, 255
red = 255, 0, 0
green = 0, 255, 0

def d2p(x1, x2, y1, y2):
	xd = x2 - x1
	yd = y2 - y1
	return math.sqrt(xd ** 2 + yd ** 2)

class engine:
	def __init__(self, width, height):		
		self.size = self.width, self.height = width, height
		self.running = True
		self.show_fps = False
		self.aaline = False
		
		self.enemies = []
		self.ships = []
		
		# state of keypresses
		self.right_pressed, self.left_pressed, self.up_pressed = False, False, False
		self.firing = False
		
		pygame.init()
		
		self.window = pygame.display.set_mode(self.size)
		self.window.fill(black)
	
	def global_draw(self):
		for x in self.ships:
			x.draw()
			for y in x.bullets:
				y.draw()
			
			for x in self.enemies:
				x.draw()
	
	def global_physics(self):
		# apply physics to every ship and bullet
		for ship in self.ships:
			ship.physics()
			
			for bullet in ship.bullets:
				bullet.physics()
				
				# check boundaries and destroy bullet if outside
				if (bullet.x > self.width) or (bullet.x < 0) or (bullet.y > self.height) or (bullet.y < 0):
					ship.bullets.remove(bullet)
					continue
				
				# destroy bullets if they are older than 1000 ms
				if bullet.death <= pygame.time.get_ticks():
					ship.bullets.remove(bullet)
					continue
				
				# check for collision
				for enemy in self.enemies:
					if d2p(bullet.x, bullet.y, enemy.x, enemy.y) <= (bullet.radius + enemy.radius):
						ship.bullets.remove(bullet)
						self.enemies.remove(enemy)

class bullet_class:
	def __init__(self, engine, parent):
		self.engine = engine
		self.parent = parent
		self.x_comp, self.y_comp = 0, 0
		self.x, self.y = self.parent.x, self.parent.y
		self.heading = self.parent.heading
		self.facing = self.parent.facing
		self.speed = 4.5
		self.radius = 3
		self.decay = 1000
		self.death = pygame.time.get_ticks() + self.decay
		self.strength = 1
		
		# calculate resultant x and y components
		self.x_comp = self.parent.speed * math.sin(self.heading) + self.speed * math.sin(self.facing)
		self.y_comp = self.parent.speed * math.cos(self.heading) + self.speed * math.cos(self.facing)
		
		# determine resultant speed
		self.speed= math.sqrt(self.x_comp ** 2 + self.y_comp ** 2)
		
		# calculate resultant heading
		if self.y_comp >= 0:
			self.heading = math.atan(self.x_comp / self.y_comp)
		elif self.y_comp < 0:
			self.heading = math.atan(self.x_comp / self.y_comp) + math.pi
	
	def draw(self):
		pygame.draw.circle(self.engine.window, green, (int(self.x), int(self.y)), self.radius)

	def physics(self):
		# adjust (x, y) according to speed
		self.x = self.x + self.speed * math.sin(self.heading)
		self.y = self.y - self.speed * math.cos(self.heading)

class enemy_class:
	def __init__(self, engine, health):
		self.engine = engine
		self.x, self.y = random.randint(1, self.engine.width), random.randint(1, self.engine.height)
		self.health = health
		self.radius = self.health
	
	def draw(self):
		pygame.draw.circle(self.engine.window, white, (int(self.x), int(self.y)), self.radius, 2)

class spaceship_class:
	def __init__(self, engine):
		self.engine = engine
		self.accel = 0.06
		self.friction = 0.01
		self.max_speed = 4
		self.rotation_rate = 5
		self.x, self.y = self.engine.width / 2, self.engine.height / 2
		self.x_comp, self.y_comp = 0, 0
		self.facing = 0
		self.heading = 0
		self.speed = 0
		self.radius = 10
		self.bullet_delay = 200
		self.last_bullet_time = 0
		
		# holds all the bullets created by this instance
		self.bullets = []
	
	def draw(self):
		# calculate vertices of the ship
		vertices = [
			(self.x + self.radius * math.sin(self.facing), self.y - self.radius * math.cos(self.facing)),
			(self.x + self.radius * math.sin(self.facing + 2 * math.pi / 3), self.y - self.radius * math.cos(self.facing + 2 * math.pi / 3)),
			(self.x + self.radius * math.sin(self.facing + 4 * math.pi / 3), self.y - self.radius * math.cos(self.facing + 4 * math.pi / 3))
		]
		
		# draw lines with the back of the ship as red (anti-aliased if needed)
		if self.engine.aaline:
			pygame.draw.aaline(self.engine.window, white, vertices[0], vertices[1])
			pygame.draw.aaline(self.engine.window, white, vertices[2], vertices[0])
			pygame.draw.aaline(self.engine.window, red, vertices[1], vertices[2])
		else:
			pygame.draw.line(self.engine.window, white, vertices[0], vertices[1], 2)
			pygame.draw.line(self.engine.window, white, vertices[2], vertices[0], 2)
			pygame.draw.line(self.engine.window, red, vertices[1], vertices[2], 2)

	def physics(self):
		if self.engine.right_pressed:
			# determine new direction
			self.facing = self.facing + (self.rotation_rate * math.pi) / 180
			
		if self.engine.left_pressed:
			# determine new direction
			self.facing = self.facing - (self.rotation_rate * math.pi) / 180
		
		if self.engine.up_pressed:
			# determine resultant x and y components
			self.x_comp = self.speed * math.sin(self.heading) + self.accel * math.sin(self.facing)
			self.y_comp = self.speed * math.cos(self.heading) + self.accel * math.cos(self.facing)
			
			# determine resultant speed
			if self.speed < self.max_speed:
				self.speed = math.sqrt(self.x_comp ** 2 + self.y_comp ** 2)
			else:
				self.speed = self.max_speed
			
			# calculate resultant heading
			if self.y_comp >= 0:
				self.heading = math.atan(self.x_comp / self.y_comp)
			elif self.y_comp < 0:
				self.heading = math.atan(self.x_comp / self.y_comp) + math.pi
		
		# create new bullet
		if self.engine.firing:
			if pygame.time.get_ticks() >= (self.last_bullet_time + self.bullet_delay):
				self.bullets.append(bullet_class(self.engine, self))
				self.last_bullet_time = pygame.time.get_ticks()
		
		# adjust speed for friction
		if self.speed > 0: self.speed = self.speed - self.friction
		
		# adjust (x, y) according to speed
		self.x = self.x + self.speed * math.sin(self.heading)
		self.y = self.y - self.speed * math.cos(self.heading)
		
		# check boundaries
		if self.x > self.engine.width: self.x = 0
		if self.x < 0: self.x = self.engine.width
		if self.y > self.engine.height: self.y = 0
		if self.y < 0: self.y = self.engine.height

if __name__ == '__main__':
	if not pygame.font:  print 'Fonts disabled!'
	if not pygame.mixer: print 'Sound disabled!'
	
	game = engine(640, 480)
	clock = pygame.time.Clock()
	
	pygame.display.set_caption('shooter test')
	
	game.ships.append(spaceship_class(game))
	
	for item in range(1, random.randint(1, 10)): game.enemies.append(enemy_class(game, random.randint(5, 15)))
	
	while game.running:
		# limit fps to 60
		clock.tick(60)
		
		# clear screen
		game.window.fill(black)
		
		# show fps
		if pygame.font and game.show_fps:
			font = pygame.font.Font(None, 16)
			text = font.render('fps ' + str(int(clock.get_fps())), 1, (150, 150, 150))
			text_position = text.get_rect(centerx = game.width / 2)
			game.window.blit(text, text_position)
		
		# handle physics and drawing
		game.global_physics()
		game.global_draw()
		
		# flip the screen
		pygame.display.update()
		
		# handle input
		for event in pygame.event.get():
			if event.type == QUIT:
				running = False
			
			# key down
			elif event.type == KEYDOWN:
				if event.key == K_ESCAPE:
					game.running = False
				elif event.key == K_RIGHT:
					game.right_pressed = True
				elif event.key == K_LEFT:
					game.left_pressed = True
				elif event.key == K_UP:
					game.up_pressed = True
				elif event.key == K_z:
					game.firing = True
				elif event.key == K_f:
					game.show_fps = not game.show_fps
				elif event.key == K_a:
					game.aaline = not game.aaline
			
			# key up
			elif event.type == KEYUP:
				if event.key == K_RIGHT:
					game.right_pressed = False
				elif event.key == K_LEFT:
					game.left_pressed = False
				elif event.key == K_UP:
					game.up_pressed = False
				elif event.key == K_z:
					game.firing = False

Revision: 3023
at May 26, 2007 05:10 by avinashv


Updated Code
# spaceship shooter test
#
# Copyright (c) 2007, Avinash Vora
# http://www.avinashv.net
#
# Source code is protected by the GNU GPL
#
# May 26
# - added randomly generated enemies
# - added engine class
# May 25
# - added maximum ship speed
# - added anti-aliasing toggle
# - changed friction from 0.0075 to 0.01
# - implemented bullets and physics
# - fully object-oriented code
# May 24
# - added FPS read-out
# - implemented ship and physics

import pygame, math, sys, random
from pygame.locals import *

black = 0, 0, 0
white = 255, 255, 255
red = 255, 0, 0
green = 0, 255, 0

def d2p(x1, x2, y1, y2):
	xd = x2 - x1
	yd = y2 - y1
	return math.sqrt(xd ** 2 + yd ** 2)

class engine:
	def __init__(self, width, height):		
		self.size = self.width, self.height = width, height
		self.running = True
		self.show_fps = False
		self.aaline = False
		
		self.enemies = []
		self.ships = []
		
		# state of keypresses
		self.right_pressed, self.left_pressed, self.up_pressed = False, False, False
		self.firing = False
		
		pygame.init()
		
		self.window = pygame.display.set_mode(self.size)
		self.window.fill(black)
	
	def global_draw(self):
		for x in self.ships:
			x.draw()
			for y in x.bullets:
				y.draw()
			
			for x in self.enemies:
				x.draw()
	
	def global_physics(self):
		# apply physics to every ship and bullet
		for ship in self.ships:
			ship.physics()
			
			for bullet in ship.bullets:
				bullet.physics()
				
				# check boundaries and destroy bullet if outside
				if (bullet.x > self.width) or (bullet.x < 0) or (bullet.y > self.height) or (bullet.y < 0):
					ship.bullets.remove(bullet)
					continue
				
				# destroy bullets if they are older than 1000 ms
				if bullet.death <= pygame.time.get_ticks():
					ship.bullets.remove(bullet)
					continue
				
				# check for collision
				for enemy in self.enemies:
					if d2p(bullet.x, bullet.y, enemy.x, enemy.y) >= (bullet.radius + enemy.radius):
						ship.bullets.remove(bullet)
						self.enemies.remove(enemy)

class bullet_class:
	def __init__(self, engine, parent):
		self.engine = engine
		self.parent = parent
		self.x_comp, self.y_comp = 0, 0
		self.x, self.y = self.parent.x, self.parent.y
		self.heading = self.parent.heading
		self.facing = self.parent.facing
		self.speed = 4.5
		self.radius = 3
		self.decay = 1000
		self.death = pygame.time.get_ticks() + self.decay
		self.strength = 1
		
		# calculate resultant x and y components
		self.x_comp = self.parent.speed * math.sin(self.heading) + self.speed * math.sin(self.facing)
		self.y_comp = self.parent.speed * math.cos(self.heading) + self.speed * math.cos(self.facing)
		
		# determine resultant speed
		self.speed= math.sqrt(self.x_comp ** 2 + self.y_comp ** 2)
		
		# calculate resultant heading
		if self.y_comp >= 0:
			self.heading = math.atan(self.x_comp / self.y_comp)
		elif self.y_comp < 0:
			self.heading = math.atan(self.x_comp / self.y_comp) + math.pi
	
	def draw(self):
		pygame.draw.circle(self.engine.window, green, (int(self.x), int(self.y)), self.radius)

	def physics(self):
		# adjust (x, y) according to speed
		self.x = self.x + self.speed * math.sin(self.heading)
		self.y = self.y - self.speed * math.cos(self.heading)

class enemy_class:
	def __init__(self, engine, health):
		self.engine = engine
		self.x, self.y = random.randint(1, self.engine.width), random.randint(1, self.engine.height)
		self.health = health
		self.radius = self.health
	
	def draw(self):
		pygame.draw.circle(self.engine.window, white, (int(self.x), int(self.y)), self.radius, 2)

class spaceship_class:
	def __init__(self, engine):
		self.engine = engine
		self.accel = 0.06
		self.friction = 0.01
		self.max_speed = 4
		self.rotation_rate = 5
		self.x, self.y = self.engine.width / 2, self.engine.height / 2
		self.x_comp, self.y_comp = 0, 0
		self.facing = 0
		self.heading = 0
		self.speed = 0
		self.radius = 10
		self.bullet_delay = 200
		self.last_bullet_time = 0
		
		# holds all the bullets created by this instance
		self.bullets = []
	
	def draw(self):
		# calculate vertices of the ship
		vertices = [
			(self.x + self.radius * math.sin(self.facing), self.y - self.radius * math.cos(self.facing)),
			(self.x + self.radius * math.sin(self.facing + 2 * math.pi / 3), self.y - self.radius * math.cos(self.facing + 2 * math.pi / 3)),
			(self.x + self.radius * math.sin(self.facing + 4 * math.pi / 3), self.y - self.radius * math.cos(self.facing + 4 * math.pi / 3))
		]
		
		# draw lines with the back of the ship as red (anti-aliased if needed)
		if self.engine.aaline:
			pygame.draw.aaline(self.engine.window, white, vertices[0], vertices[1])
			pygame.draw.aaline(self.engine.window, white, vertices[2], vertices[0])
			pygame.draw.aaline(self.engine.window, red, vertices[1], vertices[2])
		else:
			pygame.draw.line(self.engine.window, white, vertices[0], vertices[1], 2)
			pygame.draw.line(self.engine.window, white, vertices[2], vertices[0], 2)
			pygame.draw.line(self.engine.window, red, vertices[1], vertices[2], 2)

	def physics(self):
		if self.engine.right_pressed:
			# determine new direction
			self.facing = self.facing + (self.rotation_rate * math.pi) / 180
			
		if self.engine.left_pressed:
			# determine new direction
			self.facing = self.facing - (self.rotation_rate * math.pi) / 180
		
		if self.engine.up_pressed:
			# determine resultant x and y components
			self.x_comp = self.speed * math.sin(self.heading) + self.accel * math.sin(self.facing)
			self.y_comp = self.speed * math.cos(self.heading) + self.accel * math.cos(self.facing)
			
			# determine resultant speed
			if self.speed < self.max_speed:
				self.speed = math.sqrt(self.x_comp ** 2 + self.y_comp ** 2)
			else:
				self.speed = self.max_speed
			
			# calculate resultant heading
			if self.y_comp >= 0:
				self.heading = math.atan(self.x_comp / self.y_comp)
			elif self.y_comp < 0:
				self.heading = math.atan(self.x_comp / self.y_comp) + math.pi
		
		# create new bullet
		if self.engine.firing:
			if pygame.time.get_ticks() >= (self.last_bullet_time + self.bullet_delay):
				self.bullets.append(bullet_class(self.engine, self))
				self.last_bullet_time = pygame.time.get_ticks()
		
		# adjust speed for friction
		if self.speed > 0: self.speed = self.speed - self.friction
		
		# adjust (x, y) according to speed
		self.x = self.x + self.speed * math.sin(self.heading)
		self.y = self.y - self.speed * math.cos(self.heading)
		
		# check boundaries
		if self.x > self.engine.width: self.x = 0
		if self.x < 0: self.x = self.engine.width
		if self.y > self.engine.height: self.y = 0
		if self.y < 0: self.y = self.engine.height

if __name__ == '__main__':
	if not pygame.font:  print 'Fonts disabled!'
	if not pygame.mixer: print 'Sound disabled!'
	
	game = engine(640, 480)
	clock = pygame.time.Clock()
	
	pygame.display.set_caption('shooter test')
	
	game.ships.append(spaceship_class(game))
	
	for item in range(1, random.randint(1, 10)): game.enemies.append(enemy_class(game, random.randint(5, 15)))
	
	while game.running:
		# limit fps to 60
		clock.tick(60)
		
		# clear screen
		game.window.fill(black)
		
		# show fps
		if pygame.font and game.show_fps:
			font = pygame.font.Font(None, 16)
			text = font.render('fps ' + str(int(clock.get_fps())), 1, (150, 150, 150))
			text_position = text.get_rect(centerx = game.width / 2)
			game.window.blit(text, text_position)
		
		# handle physics and drawing
		game.global_physics()
		game.global_draw()
		
		# flip the screen
		pygame.display.update()
		
		# handle input
		for event in pygame.event.get():
			if event.type == QUIT:
				running = False
			
			# key down
			elif event.type == KEYDOWN:
				if event.key == K_ESCAPE:
					game.running = False
				elif event.key == K_RIGHT:
					game.right_pressed = True
				elif event.key == K_LEFT:
					game.left_pressed = True
				elif event.key == K_UP:
					game.up_pressed = True
				elif event.key == K_z:
					game.firing = True
				elif event.key == K_f:
					game.show_fps = not game.show_fps
				elif event.key == K_a:
					game.aaline = not game.aaline
			
			# key up
			elif event.type == KEYUP:
				if event.key == K_RIGHT:
					game.right_pressed = False
				elif event.key == K_LEFT:
					game.left_pressed = False
				elif event.key == K_UP:
					game.up_pressed = False
				elif event.key == K_z:
					game.firing = False

Revision: 3022
at May 25, 2007 17:22 by avinashv


Updated Code
# spaceship shooter test
####
#
# Copyright (c) 2007, Avinash Vora
# http://www.avinashv.net
#
# Source code is protected by the GNU GPL
#
# May 25
# - added maximum ship speed
# - added anti-aliasing toggle
# - changed friction from 0.0075 to 0.01
# - implemented bullets and physics
# - fully object-oriented code
# May 24
# - added FPS read-out
# - implemented ship and physics

import pygame, math, sys
from pygame.locals import *

black = 0, 0, 0
white = 255, 255, 255
red = 255, 0, 0
green = 0, 255, 0

size = width, height = 640, 480
running = True

show_fps = False

aaline = False

global window

class bullet:
	def __init__(self, parent):
		self.parent = parent
		self.x_comp, self.y_comp = 0, 0
		self.x, self.y = self.parent.x, self.parent.y
		self.heading = self.parent.heading
		self.facing = self.parent.facing
		self.speed = 4.5
		self.radius = 3
		self.decay = 1000
		self.death = pygame.time.get_ticks() + self.decay
		
		# calculate resultant x and y components
		self.x_comp = self.parent.speed * math.sin(self.heading) + self.speed * math.sin(self.facing)
		self.y_comp = self.parent.speed * math.cos(self.heading) + self.speed * math.cos(self.facing)
		
		# determine resultant speed
		self.speed= math.sqrt(self.x_comp ** 2 + self.y_comp ** 2)
		
		# calculate resultant heading
		if self.y_comp >= 0:
			self.heading = math.atan(self.x_comp / self.y_comp)
		elif self.y_comp < 0:
			self.heading = math.atan(self.x_comp / self.y_comp) + math.pi
	
	def draw(self):
		pygame.draw.circle(window, green, (int(self.x), int(self.y)), self.radius)

	def physics(self):
		# adjust (x, y) according to speed
		self.x = self.x + self.speed * math.sin(self.heading)
		self.y = self.y - self.speed * math.cos(self.heading)

class spaceship:
	def __init__(self):
		self.accel = 0.06
		self.friction = 0.01
		self.max_speed = 4
		self.rotation_rate = 5
		self.x, self.y = width / 2, height / 2
		self.x_comp, self.y_comp = 0, 0
		self.facing = 0
		self.heading = 0
		self.speed = 0
		self.radius = 10
		self.bullet_delay = 200
		self.last_bullet_time = 0
		
		# state of keypresses
		self.right_pressed, self.left_pressed, self.up_pressed = False, False, False
		self.firing = False
		
		# holds all the bullets created by this instance
		self.bullets = []
	
	def draw(self):
		# calculate vertices of the ship
		vertices = [
			(self.x + self.radius * math.sin(self.facing), self.y - self.radius * math.cos(self.facing)),
			(self.x + self.radius * math.sin(self.facing + 2 * math.pi / 3), self.y - self.radius * math.cos(self.facing + 2 * math.pi / 3)),
			(self.x + self.radius * math.sin(self.facing + 4 * math.pi / 3), self.y - self.radius * math.cos(self.facing + 4 * math.pi / 3))
		]
		
		# draw lines with the back of the ship as red (anti-aliased if needed)
		if aaline:
			pygame.draw.aaline(window, white, vertices[0], vertices[1])
			pygame.draw.aaline(window, white, vertices[2], vertices[0])
			pygame.draw.aaline(window, red, vertices[1], vertices[2])
		else:
			pygame.draw.line(window, white, vertices[0], vertices[1], 2)
			pygame.draw.line(window, white, vertices[2], vertices[0], 2)
			pygame.draw.line(window, red, vertices[1], vertices[2], 2)
		
		# draw child bullets
		for item in self.bullets:
			item.draw()

	def physics(self):
		if self.right_pressed:
			# determine new direction
			self.facing = self.facing + (self.rotation_rate * math.pi) / 180
			
		if self.left_pressed:
			# determine new direction
			self.facing = self.facing - (self.rotation_rate * math.pi) / 180
		
		if self.up_pressed:
			# determine resultant x and y components
			self.x_comp = self.speed * math.sin(ship.heading) + self.accel * math.sin(self.facing)
			self.y_comp = self.speed * math.cos(ship.heading) + self.accel * math.cos(self.facing)
			
			# determine resultant speed
			if self.speed < self.max_speed:
				self.speed = math.sqrt(self.x_comp ** 2 + self.y_comp ** 2)
			else:
				self.speed = self.max_speed
			
			# calculate resultant heading
			if self.y_comp >= 0:
				self.heading = math.atan(self.x_comp / self.y_comp)
			elif self.y_comp < 0:
				self.heading = math.atan(self.x_comp / self.y_comp) + math.pi
		
		# create new bullet
		if self.firing:
			if pygame.time.get_ticks() >= (self.last_bullet_time + self.bullet_delay):
				self.bullets.append(bullet(self))
				self.last_bullet_time = pygame.time.get_ticks()
		
		# apply physics to every bullet
		for item in self.bullets:
			item.physics()
			
			# check boundaries and destroy bullet if outside
			if (item.x > width) or (item.x < 0) or (item.y > height) or (item.y < 0):
				self.bullets.remove(item)
				continue
			
			# destroy bullets if they are older than 1000 ms
			if item.death <= pygame.time.get_ticks():
				self.bullets.remove(item)
				continue
		
		# adjust speed for friction
		if self.speed > 0: self.speed = self.speed - self.friction
		
		# adjust (x, y) according to speed
		self.x = self.x + self.speed * math.sin(self.heading)
		self.y = self.y - self.speed * math.cos(self.heading)
		
		# check boundaries
		if self.x > width: self.x = 0
		if self.x < 0: self.x = width
		if self.y > height: self.y = 0
		if self.y < 0: self.y = height
	
if __name__ == '__main__':
	if not pygame.font:  print 'Fonts disabled!'
	if not pygame.mixer: print 'Sound disabled!'
	
	pygame.init()
	
	# create window
	window = pygame.display.set_mode(size)
	window.fill(black)
	pygame.display.set_caption('shooter test')
	
	clock = pygame.time.Clock()
	
	ship = spaceship()
	ship.window = window
	
	while running:
		# limit fps to 60
		clock.tick(60)
		
		# clear screen
		window.fill(black)
		
		# show fps
		if pygame.font and show_fps:
			font = pygame.font.Font(None, 16)
			text = font.render('fps ' + str(int(clock.get_fps())), 1, (150, 150, 150))
			text_position = text.get_rect(centerx = width / 2)
			window.blit(text, text_position)
		
		# handle ship physics and drawing
		ship.physics()
		ship.draw()
		
		# flip the screen
		pygame.display.update()
		
		# handle input
		for event in pygame.event.get():
			if event.type == QUIT:
				running = False
			
			# key down
			elif event.type == KEYDOWN:
				if event.key == K_ESCAPE:
					running = False
				elif event.key == K_RIGHT:
					ship.right_pressed = True
				elif event.key == K_LEFT:
					ship.left_pressed = True
				elif event.key == K_UP:
					ship.up_pressed = True
				elif event.key == K_z:
					ship.firing = True
				elif event.key == K_f:
					show_fps = not show_fps
				elif event.key == K_a:
					aaline = not aaline
			
			# key up
			elif event.type == KEYUP:
				if event.key == K_RIGHT:
					ship.right_pressed = False
				elif event.key == K_LEFT:
					ship.left_pressed = False
				elif event.key == K_UP:
					ship.up_pressed = False
				elif event.key == K_z:
					ship.firing = False

Revision: 3021
at May 25, 2007 17:22 by avinashv


Updated Code
# spaceship shooter test
####
#
# Copyright (c) 2007, Avinash Vora
# http://www.avinashv.net
#
# Source code is protected by the GNU GPL
#
# May 25
# - added maximum ship speed
# - added anti-aliasing toggle
# - changed friction from 0.0075 to 0.01
# - implemented bullets and physics
# - fully object-oriented code
# May 24
# - added FPS read-out
# - implemented ship and physics

import pygame, math, sys
from pygame.locals import *

black = 0, 0, 0
white = 255, 255, 255
red = 255, 0, 0
green = 0, 255, 0

size = width, height = 640, 480
running = True

show_fps = False

aaline = True

global window

class bullet:
	def __init__(self, parent):
		self.parent = parent
		self.x_comp, self.y_comp = 0, 0
		self.x, self.y = self.parent.x, self.parent.y
		self.heading = self.parent.heading
		self.facing = self.parent.facing
		self.speed = 4.5
		self.radius = 3
		self.decay = 1000
		self.death = pygame.time.get_ticks() + self.decay
		
		# calculate resultant x and y components
		self.x_comp = self.parent.speed * math.sin(self.heading) + self.speed * math.sin(self.facing)
		self.y_comp = self.parent.speed * math.cos(self.heading) + self.speed * math.cos(self.facing)
		
		# determine resultant speed
		self.speed= math.sqrt(self.x_comp ** 2 + self.y_comp ** 2)
		
		# calculate resultant heading
		if self.y_comp >= 0:
			self.heading = math.atan(self.x_comp / self.y_comp)
		elif self.y_comp < 0:
			self.heading = math.atan(self.x_comp / self.y_comp) + math.pi
	
	def draw(self):
		pygame.draw.circle(window, green, (int(self.x), int(self.y)), self.radius)

	def physics(self):
		# adjust (x, y) according to speed
		self.x = self.x + self.speed * math.sin(self.heading)
		self.y = self.y - self.speed * math.cos(self.heading)

class spaceship:
	def __init__(self):
		self.accel = 0.06
		self.friction = 0.01
		self.max_speed = 4
		self.rotation_rate = 5
		self.x, self.y = width / 2, height / 2
		self.x_comp, self.y_comp = 0, 0
		self.facing = 0
		self.heading = 0
		self.speed = 0
		self.radius = 10
		self.bullet_delay = 200
		self.last_bullet_time = 0
		
		# state of keypresses
		self.right_pressed, self.left_pressed, self.up_pressed = False, False, False
		self.firing = False
		
		# holds all the bullets created by this instance
		self.bullets = []
	
	def draw(self):
		# calculate vertices of the ship
		vertices = [
			(self.x + self.radius * math.sin(self.facing), self.y - self.radius * math.cos(self.facing)),
			(self.x + self.radius * math.sin(self.facing + 2 * math.pi / 3), self.y - self.radius * math.cos(self.facing + 2 * math.pi / 3)),
			(self.x + self.radius * math.sin(self.facing + 4 * math.pi / 3), self.y - self.radius * math.cos(self.facing + 4 * math.pi / 3))
		]
		
		# draw lines with the back of the ship as red (anti-aliased if needed)
		if aaline:
			pygame.draw.aaline(window, white, vertices[0], vertices[1])
			pygame.draw.aaline(window, white, vertices[2], vertices[0])
			pygame.draw.aaline(window, red, vertices[1], vertices[2])
		else:
			pygame.draw.line(window, white, vertices[0], vertices[1], 2)
			pygame.draw.line(window, white, vertices[2], vertices[0], 2)
			pygame.draw.line(window, red, vertices[1], vertices[2], 2)
		
		# draw child bullets
		for item in self.bullets:
			item.draw()

	def physics(self):
		if self.right_pressed:
			# determine new direction
			self.facing = self.facing + (self.rotation_rate * math.pi) / 180
			
		if self.left_pressed:
			# determine new direction
			self.facing = self.facing - (self.rotation_rate * math.pi) / 180
		
		if self.up_pressed:
			# determine resultant x and y components
			self.x_comp = self.speed * math.sin(ship.heading) + self.accel * math.sin(self.facing)
			self.y_comp = self.speed * math.cos(ship.heading) + self.accel * math.cos(self.facing)
			
			# determine resultant speed
			if self.speed < self.max_speed:
				self.speed = math.sqrt(self.x_comp ** 2 + self.y_comp ** 2)
			else:
				self.speed = self.max_speed
			
			# calculate resultant heading
			if self.y_comp >= 0:
				self.heading = math.atan(self.x_comp / self.y_comp)
			elif self.y_comp < 0:
				self.heading = math.atan(self.x_comp / self.y_comp) + math.pi
		
		# create new bullet
		if self.firing:
			if pygame.time.get_ticks() >= (self.last_bullet_time + self.bullet_delay):
				self.bullets.append(bullet(self))
				self.last_bullet_time = pygame.time.get_ticks()
		
		# apply physics to every bullet
		for item in self.bullets:
			item.physics()
			
			# check boundaries and destroy bullet if outside
			if (item.x > width) or (item.x < 0) or (item.y > height) or (item.y < 0):
				self.bullets.remove(item)
				continue
			
			# destroy bullets if they are older than 1000 ms
			if item.death <= pygame.time.get_ticks():
				self.bullets.remove(item)
				continue
		
		# adjust speed for friction
		if self.speed > 0: self.speed = self.speed - self.friction
		
		# adjust (x, y) according to speed
		self.x = self.x + self.speed * math.sin(self.heading)
		self.y = self.y - self.speed * math.cos(self.heading)
		
		# check boundaries
		if self.x > width: self.x = 0
		if self.x < 0: self.x = width
		if self.y > height: self.y = 0
		if self.y < 0: self.y = height
	
if __name__ == '__main__':
	if not pygame.font:  print 'Fonts disabled!'
	if not pygame.mixer: print 'Sound disabled!'
	
	pygame.init()
	
	# create window
	window = pygame.display.set_mode(size)
	window.fill(black)
	pygame.display.set_caption('shooter test')
	
	clock = pygame.time.Clock()
	
	ship = spaceship()
	ship.window = window
	
	while running:
		# limit fps to 60
		clock.tick(60)
		
		# clear screen
		window.fill(black)
		
		# show fps
		if pygame.font and show_fps:
			font = pygame.font.Font(None, 16)
			text = font.render('fps ' + str(int(clock.get_fps())), 1, (150, 150, 150))
			text_position = text.get_rect(centerx = width / 2)
			window.blit(text, text_position)
		
		# handle ship physics and drawing
		ship.physics()
		ship.draw()
		
		# flip the screen
		pygame.display.update()
		
		# handle input
		for event in pygame.event.get():
			if event.type == QUIT:
				running = False
			
			# key down
			elif event.type == KEYDOWN:
				if event.key == K_ESCAPE:
					running = False
				elif event.key == K_RIGHT:
					ship.right_pressed = True
				elif event.key == K_LEFT:
					ship.left_pressed = True
				elif event.key == K_UP:
					ship.up_pressed = True
				elif event.key == K_z:
					ship.firing = True
				elif event.key == K_f:
					show_fps = not show_fps
				elif event.key == K_a:
					aaline = not aaline
			
			# key up
			elif event.type == KEYUP:
				if event.key == K_RIGHT:
					ship.right_pressed = False
				elif event.key == K_LEFT:
					ship.left_pressed = False
				elif event.key == K_UP:
					ship.up_pressed = False
				elif event.key == K_z:
					ship.firing = False

Revision: 3020
at May 25, 2007 06:14 by avinashv


Updated Code
import pygame, math, sys
from pygame.locals import *

black = 0, 0, 0
white = 255, 255, 255
red = 255, 0, 0
green = 0, 255, 0

size = width, height = 640, 480
running = True

show_fps = False

global window

class bullet:
	def __init__(self, parent):
		self.parent = parent
		self.x_comp, self.y_comp = 0, 0
		self.x, self.y = self.parent.x, self.parent.y
		self.heading = self.parent.heading
		self.facing = self.parent.facing
		self.speed = 4
		self.radius = 3
		self.decay = 1000
		self.death = pygame.time.get_ticks() + self.decay
		
		# calculate resultant x and y components
		self.x_comp = self.parent.speed * math.sin(self.heading) + self.speed * math.sin(self.facing)
		self.y_comp = self.parent.speed * math.cos(self.heading) + self.speed * math.cos(self.facing)
		
		# determine resultant speed
		self.speed= math.sqrt(self.x_comp ** 2 + self.y_comp ** 2)
		
		# calculate resultant heading
		if self.y_comp >= 0:
			self.heading = math.atan(self.x_comp / self.y_comp)
		elif self.y_comp < 0:
			self.heading = math.atan(self.x_comp / self.y_comp) + math.pi
	
	def draw(self):
		pygame.draw.circle(window, green, (int(self.x), int(self.y)), self.radius)

	def physics(self):
		# adjust (x, y) according to speed
		self.x = self.x + self.speed * math.sin(self.heading)
		self.y = self.y - self.speed * math.cos(self.heading)
		
		# check boundaries
		if self.x > width: self.x = 0
		if self.x < 0: self.x = width
		if self.y > height: self.y = 0
		if self.y < 0: self.y = height

class spaceship:
	def __init__(self):
		self.accel = 0.06
		self.friction = 0.0075
		self.rotation_rate = 5
		self.x, self.y = width / 2, height / 2
		self.x_comp, self.y_comp = 0, 0
		self.facing = 0
		self.heading = 0
		self.speed = 0
		self.radius = 10
		self.bullet_delay = 200
		self.last_bullet_time = 0
		
		self.right_pressed, self.left_pressed, self.up_pressed = False, False, False
		self.firing = False
		
		self.bullets = []
	
	def draw(self):
		# calculate vertices of the ship
		vertices = [
			(self.x + self.radius * math.sin(self.facing), self.y - self.radius * math.cos(self.facing)),
			(self.x + self.radius * math.sin(self.facing + 2 * math.pi / 3), self.y - self.radius * math.cos(self.facing + 2 * math.pi / 3)),
			(self.x + self.radius * math.sin(self.facing + 4 * math.pi / 3), self.y - self.radius * math.cos(self.facing + 4 * math.pi / 3))
		]
		
		# draw lines with the back of the ship as red
		pygame.draw.line(window, white, vertices[0], vertices[1], 2)
		pygame.draw.line(window, white, vertices[2], vertices[0], 2)
		pygame.draw.line(window, red, vertices[1], vertices[2], 2)
		
		# draw child bullets
		for item in self.bullets:
			item.draw()

	def physics(self):
		if self.right_pressed:
			# determine new direction
			self.facing = self.facing + (self.rotation_rate * math.pi) / 180
			
		if self.left_pressed:
			# determine new direction
			self.facing = self.facing - (self.rotation_rate * math.pi) / 180
		
		if self.up_pressed:
			# determine resultant x and y components
			self.x_comp = self.speed * math.sin(ship.heading) + self.accel * math.sin(self.facing)
			self.y_comp = self.speed * math.cos(ship.heading) + self.accel * math.cos(self.facing)
			
			# determine resultant speed
			self.speed = math.sqrt(self.x_comp ** 2 + self.y_comp ** 2)
			
			# calculate resultant heading
			if self.y_comp >= 0:
				self.heading = math.atan(self.x_comp / self.y_comp)
			elif self.y_comp < 0:
				self.heading = math.atan(self.x_comp / self.y_comp) + math.pi
		
		# create new bullet
		if self.firing:
			if pygame.time.get_ticks() >= (self.last_bullet_time + self.bullet_delay):
				self.bullets.append(bullet(self))
				self.last_bullet_time = pygame.time.get_ticks()
		
		# apply physics to every bullet
		for item in self.bullets:
			item.physics()
			if item.death <= pygame.time.get_ticks(): self.bullets.remove(item)
		
		# adjust speed for friction
		if self.speed > 0: self.speed = self.speed - self.friction
		
		# adjust (x, y) according to speed
		self.x = self.x + self.speed * math.sin(self.heading)
		self.y = self.y - self.speed * math.cos(self.heading)
		
		# check boundaries
		if self.x > width: self.x = 0
		if self.x < 0: self.x = width
		if self.y > height: self.y = 0
		if self.y < 0: self.y = height
	
if __name__ == '__main__':
	if not pygame.font:  print 'Fonts disabled!'
	if not pygame.mixer: print 'Sound disabled!'
	
	pygame.init()
	
	# create window
	window = pygame.display.set_mode(size)
	window.fill(black)
	pygame.display.set_caption('shooter test')
	
	clock = pygame.time.Clock()
	
	ship = spaceship()
	ship.window = window
	
	while running:
		# limit fps to 60
		clock.tick(60)
		
		# clear screen
		window.fill(black)
		
		# show fps
		if pygame.font and show_fps:
			font = pygame.font.Font(None, 16)
			text = font.render('fps ' + str(int(clock.get_fps())), 1, (150, 150, 150))
			text_position = text.get_rect(centerx = width / 2)
			window.blit(text, text_position)
		
		# handle ship physics and drawing
		ship.physics()
		ship.draw()
		
		# flip the screen
		pygame.display.update()
		
		# handle input
		for event in pygame.event.get():
			if event.type == QUIT:
				running = False
			
			# key down
			elif event.type == KEYDOWN:
				if event.key == K_ESCAPE:
					running = False
				elif event.key == K_RIGHT:
					ship.right_pressed = True
				elif event.key == K_LEFT:
					ship.left_pressed = True
				elif event.key == K_UP:
					ship.up_pressed = True
				elif event.key == K_z:
					ship.firing = True
				elif event.key == K_f:
					show_fps = not show_fps
			
			# key up
			elif event.type == KEYUP:
				if event.key == K_RIGHT:
					ship.right_pressed = False
				elif event.key == K_LEFT:
					ship.left_pressed = False
				elif event.key == K_UP:
					ship.up_pressed = False
				elif event.key == K_z:
					ship.firing = False

Revision: 3019
at May 25, 2007 04:44 by avinashv


Updated Code
import pygame, math, sys
from pygame.locals import *

black = 0, 0, 0
white = 255, 255, 255
red = 255, 0, 0
green = 0, 255, 0

size = width, height = 640, 480
running = True

show_fps = False

global window

class bullet:
	def __init__(self, parent):
		self.parent = parent
		self.x_comp, self.y_comp = 0, 0
		self.x, self.y = self.parent.x, self.parent.y
		self.heading = self.parent.heading
		self.facing = self.parent.facing
		self.speed = 4
		self.radius = 3
		self.decay = 1000
		self.death = pygame.time.get_ticks() + self.decay
		
		# calculate resultant x and y components
		self.x_comp = self.parent.speed * math.sin(self.heading) + self.speed * math.sin(self.facing)
		self.y_comp = self.parent.speed * math.cos(self.heading) + self.speed * math.cos(self.facing)
		
		# determine resultant speed
		self.speed= math.sqrt(self.x_comp ** 2 + self.y_comp ** 2)
		
		# calculate resultant heading
		if self.y_comp >= 0:
			self.heading = math.atan(self.x_comp / self.y_comp)
		elif self.y_comp < 0:
			self.heading = math.atan(self.x_comp / self.y_comp) + math.pi
	
	def draw(self):
		pygame.draw.circle(window, green, (int(self.x), int(self.y)), self.radius)

	def physics(self):
		# adjust (x, y) according to speed
		self.x = self.x + self.speed * math.sin(self.heading)
		self.y = self.y - self.speed * math.cos(self.heading)
		
		# check boundaries
		if self.x > width: self.x = 0
		if self.x < 0: self.x = width
		if self.y > height: self.y = 0
		if self.y < 0: self.y = height

class spaceship:
	def __init__(self):
		self.accel = 0.06
		self.friction = 0.0075
		self.rotation_rate = 5
		self.x, self.y = width / 2, height / 2
		self.x_comp, self.y_comp = 0, 0
		self.facing = 0
		self.heading = 0
		self.speed = 0
		self.radius = 10
		self.bullet_delay = 200
		self.last_bullet_time = 0
		
		self.right_pressed, self.left_pressed, self.up_pressed = False, False, False
		self.firing = False
		
		self.bullets = []
	
	def draw(self):
		# calculate vertices of the ship
		vertices = [
			(self.x + self.radius * math.sin(self.facing), self.y - self.radius * math.cos(self.facing)),
			(self.x + self.radius * math.sin(self.facing + 2 * math.pi / 3), self.y - self.radius * math.cos(self.facing + 2 * math.pi / 3)),
			(self.x + self.radius * math.sin(self.facing + 4 * math.pi / 3), self.y - self.radius * math.cos(self.facing + 4 * math.pi / 3))
		]
		
		# draw vertices with the back of the ship as red
		pygame.draw.aaline(window, white, vertices[0], vertices[1])
		pygame.draw.aaline(window, red, vertices[1], vertices[2])
		pygame.draw.aaline(window, white, vertices[2], vertices[0])
		
		# draw child bullets
		for item in self.bullets:
			item.draw()

	def physics(self):
		if self.right_pressed:
			# determine new direction
			self.facing = self.facing + (self.rotation_rate * math.pi) / 180
			
		if self.left_pressed:
			# determine new direction
			self.facing = self.facing - (self.rotation_rate * math.pi) / 180
		
		if self.up_pressed:
			# determine resultant x and y components
			self.x_comp = self.speed * math.sin(ship.heading) + self.accel * math.sin(self.facing)
			self.y_comp = self.speed * math.cos(ship.heading) + self.accel * math.cos(self.facing)
			
			# determine resultant speed
			self.speed = math.sqrt(self.x_comp ** 2 + self.y_comp ** 2)
			
			# calculate resultant heading
			if self.y_comp >= 0:
				self.heading = math.atan(self.x_comp / self.y_comp)
			elif self.y_comp < 0:
				self.heading = math.atan(self.x_comp / self.y_comp) + math.pi
		
		# create new bullet
		if self.firing:
			if pygame.time.get_ticks() >= (self.last_bullet_time + self.bullet_delay):
				self.bullets.append(bullet(self))
				self.last_bullet_time = pygame.time.get_ticks()
		
		# apply physics to every bullet
		for item in self.bullets:
			item.physics()
			if item.death <= pygame.time.get_ticks(): self.bullets.remove(item)
		
		# adjust speed for friction
		if self.speed > 0: self.speed = self.speed - self.friction
		
		# adjust (x, y) according to speed
		self.x = self.x + self.speed * math.sin(self.heading)
		self.y = self.y - self.speed * math.cos(self.heading)
		
		# check boundaries
		if self.x > width: self.x = 0
		if self.x < 0: self.x = width
		if self.y > height: self.y = 0
		if self.y < 0: self.y = height
	
if __name__ == '__main__':
	if not pygame.font:	 print 'Fonts disabled!'
	if not pygame.mixer: print 'Sound disabled!'
	
	pygame.init()
	
	# create window
	window = pygame.display.set_mode(size)
	window.fill(black)
	pygame.display.set_caption('shooter test')
	
	clock = pygame.time.Clock()
	
	ship = spaceship()
	ship.window = window
	
	while running:
		# limit fps to 60
		clock.tick(60)
		
		# clear screen
		window.fill(black)
		
		# show fps
		if pygame.font and show_fps:
			font = pygame.font.Font(None, 16)
			text = font.render('fps ' + str(int(clock.get_fps())), 1, (150, 150, 150))
			text_position = text.get_rect(centerx = width / 2)
			window.blit(text, text_position)
		
		# handle ship physics and drawing
		ship.physics()
		ship.draw()
		
		# flip the screen
		pygame.display.update()
		
		# handle input
		for event in pygame.event.get():
			if event.type == QUIT:
				running = False
			
			# key down
			elif event.type == KEYDOWN:
				if event.key == K_ESCAPE:
					running = False
				elif event.key == K_RIGHT:
					ship.right_pressed = True
				elif event.key == K_LEFT:
					ship.left_pressed = True
				elif event.key == K_UP:
					ship.up_pressed = True
				elif event.key == K_z:
					ship.firing = True
				elif event.key == K_f:
					show_fps = not show_fps
			
			# key up
			elif event.type == KEYUP:
				if event.key == K_RIGHT:
					ship.right_pressed = False
				elif event.key == K_LEFT:
					ship.left_pressed = False
				elif event.key == K_UP:
					ship.up_pressed = False
				elif event.key == K_z:
					ship.firing = False

Revision: 3018
at May 25, 2007 04:43 by avinashv


Updated Code
import pygame, math, sys
from pygame.locals import *

black = 0, 0, 0
white = 255, 255, 255
red = 255, 0, 0
green = 0, 255, 0

size = width, height = 640, 480
running = True

show_fps = False

global window

class bullet:
	def __init__(self, parent):
		self.parent = parent
		self.x_comp, self.y_comp = 0, 0
		self.x, self.y = self.parent.x, self.parent.y
		self.heading = self.parent.heading
		self.facing = self.parent.facing
		self.speed = 4
		self.radius = 3
		self.decay = 1000
		self.death = pygame.time.get_ticks() + self.decay
		
		# calculate resultant x and y components
		self.x_comp = self.parent.speed * math.sin(self.heading) + self.speed * math.sin(self.facing)
		self.y_comp = self.parent.speed * math.cos(self.heading) + self.speed * math.cos(self.facing)
		
		# determine resultant speed
		self.speed= math.sqrt(self.x_comp ** 2 + self.y_comp ** 2)
		
		# calculate resultant heading
		if self.y_comp >= 0:
			self.heading = math.atan(self.x_comp / self.y_comp)
		elif self.y_comp < 0:
			self.heading = math.atan(self.x_comp / self.y_comp) + math.pi
	
	def draw(self):
		# calculate vertices of the ship
		pygame.draw.circle(window, green, (int(self.x), int(self.y)), self.radius)

	def physics(self):
		# adjust (x, y) according to speed
		self.x = self.x + self.speed * math.sin(self.heading)
		self.y = self.y - self.speed * math.cos(self.heading)
		
		# check boundaries
		if self.x > width: self.x = 0
		if self.x < 0: self.x = width
		if self.y > height: self.y = 0
		if self.y < 0: self.y = height

class spaceship:
	def __init__(self):
		self.accel = 0.06
		self.friction = 0.0075
		self.rotation_rate = 5
		self.x, self.y = width / 2, height / 2
		self.x_comp, self.y_comp = 0, 0
		self.facing = 0
		self.heading = 0
		self.speed = 0
		self.radius = 10
		self.bullet_delay = 200
		self.last_bullet_time = 0
		
		self.right_pressed, self.left_pressed, self.up_pressed = False, False, False
		self.firing = False
		
		self.bullets = []
	
	def draw(self):
		# calculate vertices of the ship
		vertices = [
			(self.x + self.radius * math.sin(self.facing), self.y - self.radius * math.cos(self.facing)),
			(self.x + self.radius * math.sin(self.facing + 2 * math.pi / 3), self.y - self.radius * math.cos(self.facing + 2 * math.pi / 3)),
			(self.x + self.radius * math.sin(self.facing + 4 * math.pi / 3), self.y - self.radius * math.cos(self.facing + 4 * math.pi / 3))
		]
		
		# draw vertices with the back of the ship as red
		pygame.draw.aaline(window, white, vertices[0], vertices[1])
		pygame.draw.aaline(window, red, vertices[1], vertices[2])
		pygame.draw.aaline(window, white, vertices[2], vertices[0])
		
		# draw child bullets
		for item in self.bullets:
			item.draw()

	def physics(self):
		if self.right_pressed:
			# determine new direction
			self.facing = self.facing + (self.rotation_rate * math.pi) / 180
			
		if self.left_pressed:
			# determine new direction
			self.facing = self.facing - (self.rotation_rate * math.pi) / 180
		
		if self.up_pressed:
			# determine resultant x and y components
			self.x_comp = self.speed * math.sin(ship.heading) + self.accel * math.sin(self.facing)
			self.y_comp = self.speed * math.cos(ship.heading) + self.accel * math.cos(self.facing)
			
			# determine resultant speed
			self.speed = math.sqrt(self.x_comp ** 2 + self.y_comp ** 2)
			
			# calculate resultant heading
			if self.y_comp >= 0:
				self.heading = math.atan(self.x_comp / self.y_comp)
			elif self.y_comp < 0:
				self.heading = math.atan(self.x_comp / self.y_comp) + math.pi
		
		# create new bullet
		if self.firing:
			if pygame.time.get_ticks() >= (self.last_bullet_time + self.bullet_delay):
				self.bullets.append(bullet(self))
				self.last_bullet_time = pygame.time.get_ticks()
		
		# apply physics to every bullet
		for item in self.bullets:
			item.physics()
			if item.death <= pygame.time.get_ticks(): self.bullets.remove(item)
		
		# adjust speed for friction
		if self.speed > 0: self.speed = self.speed - self.friction
		
		# adjust (x, y) according to speed
		self.x = self.x + self.speed * math.sin(self.heading)
		self.y = self.y - self.speed * math.cos(self.heading)
		
		# check boundaries
		if self.x > width: self.x = 0
		if self.x < 0: self.x = width
		if self.y > height: self.y = 0
		if self.y < 0: self.y = height
	
if __name__ == '__main__':
	if not pygame.font:	 print 'Fonts disabled!'
	if not pygame.mixer: print 'Sound disabled!'
	
	pygame.init()
	
	# create window
	window = pygame.display.set_mode(size)
	window.fill(black)
	pygame.display.set_caption('shooter test')
	
	clock = pygame.time.Clock()
	
	ship = spaceship()
	ship.window = window
	
	while running:
		# limit fps to 60
		clock.tick(60)
		
		# clear screen
		window.fill(black)
		
		# show fps
		if pygame.font and show_fps:
			font = pygame.font.Font(None, 16)
			text = font.render('fps ' + str(int(clock.get_fps())), 1, (150, 150, 150))
			text_position = text.get_rect(centerx = width / 2)
			window.blit(text, text_position)
		
		# handle ship physics and drawing
		ship.physics()
		ship.draw()
		
		# flip the screen
		pygame.display.update()
		
		# handle input
		for event in pygame.event.get():
			if event.type == QUIT:
				running = False
			
			# key down
			elif event.type == KEYDOWN:
				if event.key == K_ESCAPE:
					running = False
				elif event.key == K_RIGHT:
					ship.right_pressed = True
				elif event.key == K_LEFT:
					ship.left_pressed = True
				elif event.key == K_UP:
					ship.up_pressed = True
				elif event.key == K_z:
					ship.firing = True
				elif event.key == K_f:
					show_fps = not show_fps
			
			# key up
			elif event.type == KEYUP:
				if event.key == K_RIGHT:
					ship.right_pressed = False
				elif event.key == K_LEFT:
					ship.left_pressed = False
				elif event.key == K_UP:
					ship.up_pressed = False
				elif event.key == K_z:
					ship.firing = False

Revision: 3017
at May 25, 2007 04:10 by avinashv


Initial Code
import pygame, math, sys
from pygame.locals import *

black = 0, 0, 0
white = 255, 255, 255
red = 255, 0, 0

size = width, height = 640, 480
running = True

show_fps = False

global window

class bullet:
	def __init__(self, parent):
		self.parent = parent
		self.x, self.y = self.parent.x, self.parent.x
		self.x_comp, self.y_comp = 0, 0
		self.heading = self.parent.heading
		self.speed = 5
		self.radius = 3
		self.decay = 700
		self.death = pygame.time.get_ticks() + self.decay
	
	def draw(self):
		# calculate vertices of the ship
		pygame.draw.circle(window, red, (self.x, self.y), self.radius)

	def physics(self):
		# determine resultant x and y components
		self.x_comp = self.speed * math.sin(self.heading)
		self.y_comp = self.speed * math.cos(self.heading)
			
		# adjust (x, y) according to speed
		self.x = self.x + self.speed * math.sin(self.heading)
		self.y = self.y - self.speed * math.cos(self.heading)
		
		# check boundaries
		if self.x > width: self.x = 0
		if self.x < 0: self.x = width
		if self.y > height: self.y = 0
		if self.y < 0: self.y = height

class spaceship:
	def __init__(self):
		self.accel = 0.06
		self.friction = 0.0075
		self.rotation_rate = 5
		self.x, self.y = width / 2, height / 2
		self.x_comp, self.y_comp = 0, 0
		self.facing = 0
		self.heading = 0
		self.speed = 0
		self.radius = 10
		
		self.right_pressed, self.left_pressed, self.up_pressed = False, False, False
		self.firing = False
		
		self.bullets = []
	
	def draw(self):
		# calculate vertices of the ship
		vertices = [
			(self.x + self.radius * math.sin(self.facing), self.y - self.radius * math.cos(self.facing)),
			(self.x + self.radius * math.sin(self.facing + 2 * math.pi / 3), self.y - self.radius * math.cos(self.facing + 2 * math.pi / 3)),
			(self.x + self.radius * math.sin(self.facing + 4 * math.pi / 3), self.y - self.radius * math.cos(self.facing + 4 * math.pi / 3))
		]
		
		# draw vertices with the back of the ship as red
		pygame.draw.aaline(window, white, vertices[0], vertices[1])
		pygame.draw.aaline(window, red, vertices[1], vertices[2])
		pygame.draw.aaline(window, white, vertices[2], vertices[0])
		
		# draw child bullets
		for item in self.bullets:
			item.draw()

	def physics(self):
		if self.right_pressed:
			# determine new direction
			self.facing = self.facing + (self.rotation_rate * math.pi) / 180
			
		if self.left_pressed:
			# determine new direction
			self.facing = self.facing - (self.rotation_rate * math.pi) / 180
		
		if self.up_pressed:
			# determine resultant x and y components
			self.x_comp = self.speed * math.sin(ship.heading) + self.accel * math.sin(self.facing)
			self.y_comp = self.speed * math.cos(ship.heading) + self.accel * math.cos(self.facing)
			
			# determine resultant speed
			self.speed = math.sqrt(self.x_comp ** 2 + self.y_comp ** 2)
			
			# calculate resultant heading
			if self.y_comp >= 0:
				self.heading = math.atan(self.x_comp / self.y_comp)
			elif self.y_comp < 0:
				self.heading = math.atan(self.x_comp / self.y_comp) + math.pi
		
		# create new bullet
		if self.firing:
			self.bullets.append(bullet(self))
		
		# apply physics to every bullet
		for item in self.bullets:
			item.physics()
			if item.death == pygame.time.get_ticks(): del item
		
		# adjust speed for friction
		if self.speed > 0: self.speed = self.speed - self.friction
		
		# adjust (x, y) according to speed
		self.x = self.x + self.speed * math.sin(self.heading)
		self.y = self.y - self.speed * math.cos(self.heading)
		
		# check boundaries
		if self.x > width: self.x = 0
		if self.x < 0: self.x = width
		if self.y > height: self.y = 0
		if self.y < 0: self.y = height
	
if __name__ == '__main__':
	if not pygame.font:	 print 'Fonts disabled!'
	if not pygame.mixer: print 'Sound disabled!'
	
	pygame.init()
	
	# create window
	window = pygame.display.set_mode(size)
	window.fill(black)
	pygame.display.set_caption('shooter test')
	
	clock = pygame.time.Clock()
	
	ship = spaceship()
	ship.window = window
	
	while running:
		# limit fps to 60
		clock.tick(60)
		
		# clear screen
		window.fill(black)
		
		# show fps
		if pygame.font and show_fps:
			font = pygame.font.Font(None, 16)
			text = font.render('fps ' + str(int(clock.get_fps())), 1, (150, 150, 150))
			text_position = text.get_rect(centerx = width / 2)
			window.blit(text, text_position)
		
		# handle ship physics and drawing
		ship.physics()
		ship.draw()
		
		# flip the screen
		pygame.display.update()
		
		# handle input
		for event in pygame.event.get():
			if event.type == QUIT:
				running = False
			
			# key down
			elif event.type == KEYDOWN:
				if event.key == K_ESCAPE:
					running = False
				elif event.key == K_RIGHT:
					ship.right_pressed = True
				elif event.key == K_LEFT:
					ship.left_pressed = True
				elif event.key == K_UP:
					ship.up_pressed = True
				elif event.key == K_z:
					ship.firing = True
				elif event.key == K_f:
					show_fps = not show_fps
			
			# key up
			elif event.type == KEYUP:
				if event.key == K_RIGHT:
					ship.right_pressed = False
				elif event.key == K_LEFT:
					ship.left_pressed = False
				elif event.key == K_UP:
					ship.up_pressed = False
				elif event.key == K_z:
					ship.firing = False

Initial URL


Initial Description
Code is GPL

Left/Right to rotate ship, Up for thrust, z to fire.
a to toggle anti-aliasing

debug - f for FPS

by Avinash Vora

Initial Title
spaceship shooter demo

Initial Tags


Initial Language
Python