Ninjar game snippet

Tags: , ,

Ninjar below birds Ninjar destroying birds

Our Ninjar exists in perfect Ninjar tranquility, upon a finite plane of austere Zen contemplation. Only the incessant, infinite flights of confetti filled combustible birds mar this ultimate Ninjar existence. Armed only with his flying kick of compassion, our Ninjar may attempt to rid the sky of these airborne abominations, but ultimately must come to realise that external actions are meaningless and true Zen is found only by acting on the world within.

(Unoptimised PyGame example)

Download Ninjar (requires Python, Pygame)

Python source:

#Ninjar 11:04 AM 19/03/2010

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

class Ninja:
	def __init__(self, sprites):
		self.sprites = sprites #sprite array
		self.x = 400
		self.y_offset = 400 #height from floor. POSITIVE IS UP
		self.baseFrame = 0 #animation cycle baseframe
		self.f = 0 #frame to use to draw this char

		self.yImpulse = 0 #jump impulse
		self.health = 10

		self.vx = 0 #x momentum
		self.facing = True #True is right, False is left
		self.control_x = 0 #-1 = left, 0 = neutral, 1 = right
		self.control_jump = False #0 = not jumping, #1 = trying to jump
		self.control_attack = False
		self.control_duck = False
		self.timer_attack = 0 #time until can attack again
		self.attacking = False

	def tick(self):
		#See if we need to update the facing position and x velocity
		#when airborne we have less control over x
		if self.control_x == -1: #heading left
			self.facing = False
			if self.y_offset > 0:
				self.vx -= 1

			else:
				self.vx -= 3
				self.baseFrame += 1
		elif self.control_x == 1: #heading right
			self.facing = True
			if self.y_offset > 0:
				self.vx += 1
			else:
				self.vx += 3
				self.baseFrame += 1

		else: #not actively running, slow down a bit
			if self.vx > 0:
				self.vx = max(0, self.vx - 2)
			if self.vx < 0:
				self.vx = min(0, self.vx + 2)
			self.baseFrame = 0

		#Are we airborne?
		if self.y_offset > 0:

			if self.attacking:
				if self.facing:
					self.f = 1 #kick right
				else:
					self.f = 12 #kick left
			else:
				if self.facing:
					self.f = 0 #duck right
				else:
					self.f = 11 #duck left

				#Are we trying to attack?
				if self.control_attack and not self.timer_attack:
					self.timer_attack = 10
					self.attacking = True
					if self.facing:
						self.f = 1 #kick right
					else:
						self.f = 12 #kick left

			#Are we still going up?
			if self.yImpulse > 0:
				#slow down a bit
				self.yImpulse -= 1
				self.y_offset += self.yImpulse
			else: #Gravity time
				self.y_offset = max(self.y_offset - 8, 0)

		else: #we're not airborne, consider ground options
			self.attacking = False #we're not attacking if we're on the ground
			if self.control_duck: #if we're trying to duck
				if self.facing:
					self.f = 0 #duck right
				else:
					self.f = 11 #duck left

				#skid to a halt
				if self.vx > 0:
					self.vx = max(0, self.vx - 3)
				if self.vx < 0:
					self.vx = min(0, self.vx + 3)

			elif self.control_jump: #we're trying to jump?
				self.yImpulse = 24
				self.y_offset = 16

			else:
				self.f = self.baseFrame % 9 + 2
				if not self.facing:
					self.f += 11

		#attack timer countdown
		self.timer_attack = max(self.timer_attack - 1, 0)

		#impose maximum horizontal velocity
		if self.vx > 0:
			self.vx = min(9, self.vx)
		if self.vx < 0:
			self.vx = max(-9, self.vx)

		self.x += self.vx
		if self.x > 850:
			self.x = -25
		if self.x < -25:
			self.x = 825

	def draw(self, surface):
		surface.blit(self.sprites[self.f], (self.x, 364 - self.y_offset))

class Ninjar:
	def __init__(self):

		self.size = 800, 480 #set screen dimensions
		pygame.init() #start pygame
                pygame.mouse.set_visible(False)

		#Set up the screen
		pygame.display.set_caption("NINJAR 0")
		self.surface = pygame.display.set_mode(self.size, pygame.FULLSCREEN)
		self.background = pygame.image.load("sprites/background.png")

		#Set up game clock for framerate control
		self.clock = pygame.time.Clock()

		#Load sprites

		#Red sprites 0=duck right, 1=kick right 2->10=walk right, 11=duck left, 12 = kick right, 13->22=walk left
		self.redSprites = []
		duckSprite = pygame.image.load("sprites/ninja_red_r_duck.png").convert_alpha()
		kickSprite = pygame.image.load("sprites/ninja_red_r_kick.png").convert_alpha()
		self.redSprites.append(duckSprite)
		self.redSprites.append(kickSprite)

		for i in range(0,9):
			walkSprite = pygame.image.load("sprites/ninja_red_r_"+str(i)+".png").convert_alpha()
			self.redSprites.append(walkSprite)

		#Mirror loaded sprites for left frames
		for i in range(len(self.redSprites)):
			walkSprite = pygame.transform.flip(self.redSprites[i], True, False)
			self.redSprites.append(walkSprite)

		self.redNinja = Ninja(self.redSprites)
		self.ninjas = []
		self.ninjas.append(self.redNinja)

		#set us up the birdies
		self.birds = []
		self.birdFrames = []
		for i in range(6):
			frame = pygame.Surface((12, abs(3 - i)*3+1))
			frame.fill((200, 200, 200))
			self.birdFrames.append(frame)
		self.birdBlood = pygame.Surface((6,6))
		self.birdBlood.fill((255,64,64))

		self.gibs = []
		self.deathzone = pygame.Rect(0,0,0,0)

	def createBird(self):
		self.birds.append([-3.0,150.0+100.0*random.random(), int(random.random()*6)])

	def createGib(self, x, y):
		dx = random.random() * 20 - 10
		dy = random.random() * -10
		self.gibs.append((x,y,dx,dy))

	#Main gameloop
	def tick(self):
		self.clock.tick(30) #limit framerate to 30 fps
                dirtyRects = [] #list of dirty rect areas to update
		self.surface.blit(self.background, (0,0)) #redraw background

		for ninja in self.ninjas:
                        rect = (ninja.x, 364 - ninja.y_offset, 16, 64)
                        dirtyRects.append(rect)
			ninja.tick()
                        rect = (ninja.x, 364 - ninja.y_offset, 16, 64)
                        dirtyRects.append(rect)
			ninja.draw(self.surface)
			if ninja.attacking:
				xOffset = 24
				if not ninja.facing:
					xOffset = -3
				self.deathzone = pygame.Rect((ninja.x + xOffset,358 - (ninja.y_offset-56)), (20,20))

		#add more birds?
		if len(self.birds) < 100:
			if random.random() > 0.95:
				self.createBird()

		#Move and draw the birds
		for i in range(len(self.birds)):
			bird = self.birds[i]
                        rect = (bird[0], bird[1], 12, 12)
                        dirtyRects.append(rect)
			#Move bird
			x = bird[0] + random.random() * 6
			if x > self.size[0]:
				x = -20
			y = bird[1] + random.random()*5 - 2.5
			y = max( 110, min(350, y))
			f = (bird[2] + 1) % 6
                        rect = (bird[0], bird[1], 12, 12)
                        dirtyRects.append(rect)

			#test for death
			birdRect = pygame.Rect(x,y,12,12)
			if birdRect.colliderect(self.deathzone):
				gibCount = int(5 + random.random() * 5)
				for j in range(gibCount):
					self.createGib(x,y)

				x = -(10 + random.random()*100)

			self.birds[i] = (x, y, f)

			#Draw bird
			self.surface.blit(self.birdFrames[3], (x+4, y))
			self.surface.blit(self.birdFrames[4], (x-2, y))
			self.surface.blit(self.birdFrames[f], (x, y))

		#handle gibs
		for i in range(len(self.gibs)):
			gib = self.gibs[i]
                        rect = (gib[0], gib[1], 6, 6)
                        dirtyRects.append(rect)

			x = gib[0] + gib[2]
			y = gib[1] + gib[3]
			dx = gib[2] * 0.95
			dy = gib[3] + 0.5

			self.gibs[i] = (x,y,dx,dy)
                        rect = (gib[0], gib[1], 6, 6)
                        dirtyRects.append(rect)

			self.surface.blit(self.birdBlood, (x,y))

		for gib in self.gibs:
			if gib[1] > 420:
				self.background.blit(self.birdBlood, (gib[0], gib[1]))
				self.gibs.remove(gib)

		#handle pygame events
		for event in pygame.event.get():
			if event.type == pygame.QUIT:
				sys.exit()

			if event.type == pygame.KEYDOWN:
				#Up cursor
				if event.key == 273:
					self.redNinja.control_jump = True

				#Down cursor
				if event.key == 274:
					self.redNinja.control_duck = True

				#Right cursor
				if event.key == 275:
					self.redNinja.control_x = +1

				#Left cursor
				if event.key == 276:
					self.redNinja.control_x = -1

				#Space
				if event.key == 32:
					self.redNinja.control_attack = True

			if event.type == pygame.KEYUP:
				#Up cursor
				if event.key == 273:
					self.redNinja.control_jump = False

				#Down cursor
				if event.key == 274:
					self.redNinja.control_duck = False

				#Right cursor
				if event.key == 275:
					self.redNinja.control_x = 0

				#Left cursor
				if event.key == 276:
					self.redNinja.control_x = 0

				#Space
				if event.key == 32:
					self.redNinja.control_attack = False

		#Commit graphical changes to display
		#pygame.display.flip()
                pygame.display.update(dirtyRects)

app = Ninjar()
while True:
	app.tick()

Leave a Reply