Jeu de tir 360° avec pygame

Soyez le premier à donner votre avis sur cette source.

Vue 11 070 fois - Téléchargée 795 fois

Description

C'est un petit jeu de tir dans lequel on contrôle une tourelle qui doit détruire des virus. Il se joue à la souris et ne contient aucune image. Tout est dessiné à l'aide du module pygame.draw.

Source / Exemple :


#!/usr/bin/python
#-*- coding:UTF-8 -*-
# -----
# VirShoot
# Créé par KS
# -----
###############################################################################
# Initialisation ##############################################################
###############################################################################

####################
# Modules ##########
####################

import pygame, sys
from pygame.locals import *
from math import sin, cos, atan2, pi
from random import random, randrange

pygame.font.init()

#####################
# Constantes ########
#####################

size = width, height = 800, 600
screen = 0

background = ((0, 150, 0), (0, 255, 0))
infos = ((0, 0, 255), (150, 150, 255), (255, 255, 0))
hero = ((255, 255, 0),(0,0,0), (100, 100, 100), (255, 0, 0), (200, 200, 200))
ennemi = ((150, 0, 0), (255, 150, 150))

################################################################################
# Fonctions ####################################################################
################################################################################

def arriereplan(surface):
	#Trafce les lignes à l'arrière plan. C'est la fonction utilisée pour effacer l'écran.
        global background, width, height
        surface.fill(background[0])
        i = width / 10
        while i < width:
                pygame.draw.line(surface, background[1], (i, 0), (i, height))
                i += width / 10
        i = height / 10
        while i < height:
                pygame.draw.line(surface, background[1], (0, i), (width, i))
                i += height / 10

def intro(ecran):
	#Début du jeu - Affichage du titre, du meilleur score.
        global screen, background, size
	
	#Récupération du score
        score = open("best.sc", "r")
        scoretxt = score.readline()

        infos = ["","",""]
        i = 0
        j = 0
        while i < len(scoretxt):
                if not scoretxt[i] == ":":
                        infos[j] += scoretxt[i]
                else:
                        j += 1
                i += 1
        
	#Boucle de présentation
        continuer = 1
        while continuer:
                arriereplan(ecran)
                
                titreu = pygame.font.Font("freesansbold.ttf", 100).render("VIRTUAL", 1, background[1])
                titruect = titreu.get_rect()
                titruect.center = (width/2 - 100, 60)

                titred = pygame.font.Font("freesansbold.ttf", 100).render("SHOOTER", 1, background[1])
                titrdrect = titred.get_rect()
                titrdrect.center = (width/2 + 100, 160)

                meilleur = pygame.font.Font("freesansbold.ttf", 50).render(infos[0]+" a fait "+infos[1] + " points en "+ infos[2] + " frames", 1, background[1])

                if meilleur.get_width() > width:
                        meilleur = pygame.transform.scale(meilleur, (width - 100, meilleur.get_height() * (width - 100) / meilleur.get_width()))
                meilleurect = meilleur.get_rect()
                meilleurect.center = (width / 2, height / 2)
                

                press = pygame.font.Font("freesansbold.ttf", 20).render("Entree pour continuer - F7 pour le mode plein ecran", 1, background[1])
                pressrect = press.get_rect()
                pressrect.center = (width / 2, height - 30)

                ecran.blit(titreu, titruect)
                ecran.blit(titred, titrdrect)
                ecran.blit(meilleur, meilleurect)
                ecran.blit(press, pressrect)

                pygame.display.flip()

		#On quitte si le joueur appuie sur echap, on alterne plein écran/fenêtré si le joueur appuie sur F7
		# et on lance le jeu si le joueur appuie sur entrée
                for event in pygame.event.get():
                        if event.type == QUIT or pygame.key.get_pressed()[K_ESCAPE]:
                                bye()
                        if pygame.key.get_pressed()[K_RETURN]:
                                continuer = 0
                        if pygame.key.get_pressed()[K_F7]:
                                screen = chgscreen(ecran, size, screen)

def jeu(ecran,curseur):
	#Le jeu en lui-même
        global width, height, screen
        heros = Hero((width/2, height/2), ecran)
        ennemis = Controlleur(heros, ecran)
	
	#Boucle de jeu
        while heros.vie > 0:
                arriereplan(ecran)
                heros.update()
                ennemis.update()

                curseur.update()
                pygame.display.flip()
                for event in pygame.event.get():
                        if event.type == QUIT or pygame.key.get_pressed()[K_ESCAPE]:
                                bye()
                        if pygame.key.get_pressed()[K_F7]:
                                screen = chgscreen(ecran, size, screen)
                pygame.time.delay(10)

        end(ecran, ennemis.score, ennemis.temps)

def end(surface, score, temps):
	#Fin de la partie - écriture du score si c'est le meilleur
        global background, width, height
          
        highscores = open("best.sc","r")
        highscore = highscores.readline()
        highscores.close()
        
        ligne = ["","",""]
        i = 0
        j = 0
        while i < len(highscore):
                if not highscore[i] == ":":
                        ligne[j] += highscore[i]
                else:
                        j += 1
                i += 1
        bestscore = int(ligne[1]) + int(ligne[2])
	#Si le joueur a fait le meilleur score...
        if score + temps > bestscore:
                nom = ""
                while not pygame.key.get_pressed()[K_RETURN]:
                        arriereplan(surface)
 			
			#Affichage du score
                        infoscore = pygame.font.Font("freesansbold.ttf", 50).render("Score: "+str(score+temps), 1, background[1])
                        inforect = infoscore.get_rect()
                        inforect.center = (width / 2, 20)
			
			#Affichage du nom choisi
                        nomtxt = pygame.font.Font("freesansbold.ttf", 50).render("Votre nom: "+nom, 1, background[1])
                        #On diminue la surface du texte s'il dépasse la fenêtre
			if nomtxt.get_width() > width:
                                nomtxt = pygame.transform.scale(nomtxt, (width - 100, nomtxt.get_height() * (width-100) / nomtxt.get_width()))
                        nomrect = nomtxt.get_rect()
                        nomrect.center = (width/2, height/2)

                        press = pygame.font.Font("freesansbold.ttf",20).render("Appuyez sur entree pour continuer", 1, background[1])
                        pressrect = press.get_rect()
                        pressrect.center = (width/2, height - 30)
			
			#Entrée du nom
                        for event in pygame.event.get():
                                keys = pygame.key.get_pressed()
                                lettres = {keys[K_q]:"a",keys[K_b]:"b",keys[K_c]:"c",keys[K_d]:"d",keys[K_e]:"e",keys[K_f]:"f",keys[K_g]:"g",keys[K_h]:"h",keys[K_i]:"i",keys[K_j]:"j",keys[K_k]:"k",keys[K_l]:"l",keys[K_SEMICOLON]:"m",
                                           keys[K_n]:"n",keys[K_o]:"o",keys[K_p]:"p",keys[K_a]:"q",keys[K_r]:"r",keys[K_s]:"s",keys[K_t]:"t",keys[K_u]:"u",keys[K_v]:"v",keys[K_z]:"w",keys[K_x]:"x",keys[K_y]:"y",keys[K_w]:"z",
                                                   keys[K_SPACE]:" "}
                                try:
                                        nom += lettres[1]
                                except:
                                        pass
                                if pygame.key.get_pressed()[K_BACKSPACE]:
                                        i = 0
                                        temp = ""
                                        while i < len(nom) - 1:
                                                temp += nom[i]
                                                i += 1
                                        nom = temp
                                if event.type == QUIT or pygame.key.get_pressed()[K_ESCAPE]:
                                        bye()

                        surface.blit(infoscore, inforect)
                        surface.blit(nomtxt, nomrect)
                        surface.blit(press, pressrect)

                        pygame.display.flip()
		
		#Ecriture du score
                writescore = open("best.sc", "w")
                writescore.write(nom + ":" + str(score) + ":" + str(temps))
                writescore.close()
	#Sinon...
        else:
                while not pygame.key.get_pressed()[K_RETURN]:
                        arriereplan(surface)
                        
                        infoscore = pygame.font.Font("freesansbold.ttf", 50).render("Score: "+str(score.temps), 1, background[1])
                        inforect = infoscore.get_rect()
                        inforect.center = (width / 2, 20)

                        press = pygame.font.Font("freesansbold.ttf",20).render("Appuyez sur entree pour continuer", 1, background[1])
                        pressrect = press.get_rect()
                        pressrect.center = (width/2, height - 10)

                        surface.blit(infoscore, inforect)
                        surface.blit(press, pressrect)

                        pygame.display.flip()
                

def chgscreen(surface, size, state):
	#On alterne entre plein écran/fenêtré
        if state == 0:
                surface = pygame.display.set_mode(size, FULLSCREEN)
                state = 1
        else:
                surface = pygame.display.set_mode(size)
                state = 0
        return state

def bye():
	#On qutte le programme
        pygame.quit()
        sys.exit()

################################################################################
# Classes ######################################################################
################################################################################

class Hero():
        "Classe du heros"
        speed = 30
        viemax = 10
        vie = 10
        rayon = 20
        canon = 50
        tirs = []
        delaimax = 5
        delai = 0
        def __init__(self, pos, surface, colors=hero):
                "Initialisation"
                self.pos = pos
                self.colors = colors
                self.surface = surface

        def update(self):
                "Actions et mise à jour de la tourelle"
                if not pygame.mouse.get_pressed()[2]:
                        self.pos = (self.pos[0] + (pygame.mouse.get_pos()[0] - self.pos[0]) / self.speed, self.pos[1] + (pygame.mouse.get_pos()[1] - self.pos[1]) / self.speed)

                angle = atan2(pygame.mouse.get_pos()[1] - self.pos[1], pygame.mouse.get_pos()[0] - self.pos[0])
                
                #On dessine le rectangle avec la fonction draw.polygon
                pygame.draw.polygon(self.surface, self.colors[2], [(self.pos[0] + cos(angle + pi/2) * 5, self.pos[1] + sin(angle+pi/2) *5),
                                                                                                                  (self.pos[0] + cos(angle - pi/2) * 5, self.pos[1] + sin(angle-pi/2) *5),
                                                                                                                  (self.pos[0] + cos(angle) * self.canon + cos(angle - pi /2) * 5, self.pos[1] + sin(angle) *self.canon + sin(angle - pi/2) *5),
                                                                                                                  (self.pos[0] + cos(angle) * self.canon + cos(angle + pi/2) *5, self.pos[1] + sin(angle) *self.canon + sin(angle + pi/2) *5)]
                                                        )
                pygame.draw.polygon(self.surface, self.colors[1], [(self.pos[0] + cos(angle + pi/2) * 5, self.pos[1] + sin(angle+pi/2) *5),
                                                                                                                  (self.pos[0] + cos(angle - pi/2) * 5, self.pos[1] + sin(angle-pi/2) *5),
                                                                                                                  (self.pos[0] + cos(angle) * self.canon + cos(angle - pi /2) * 5, self.pos[1] + sin(angle) *self.canon + sin(angle - pi/2) *5),
                                                                                                                  (self.pos[0] + cos(angle) * self.canon + cos(angle + pi/2) *5, self.pos[1] + sin(angle) *self.canon + sin(angle + pi/2) *5)],
                                                        1)
                #Dessin du corps de la tourelle
                pygame.draw.circle(self.surface, self.colors[0], self.pos, self.rayon)
                pygame.draw.circle(self.surface, self.colors[1], self.pos, self.rayon, 1)
                if self.vie < self.viemax:
                        pygame.draw.circle(self.surface, self.colors[3], self.pos, (self.viemax-self.vie) * self.rayon / self.viemax)
                
		#Gestion des tirs
                if pygame.mouse.get_pressed()[0] and self.delai == 0:
                        self.tirs.append(Tir((self.pos[0] + cos(angle) * self.canon, self.pos[1] + sin(angle) * self.canon), angle + (random() - 0.5) * (20*pi/180), len(self.tirs), self, self.surface))
                        self.delai = self.delaimax

                if self.delai:
                        self.delai -= 1
                        
		#Mise à jour des tirs
                i = 0
                while i < len(self.tirs):
                        self.tirs[i].update()
                        i += 1
                        
        def delete(self, nom):
                "Efface les tirs de la tourelle"
                self.tirs[nom: nom+1] = []
                i = nom
                while i < len(self.tirs):
                        self.tirs[i].id = i
                        i += 1

class Tir():
        "Classe de tirs"
        speed = 10
        rayon = 5
        def __init__(self, pos, angle, nom, maitre, surface):
                "Initialisation"
                self.pos = pos
                self.move = (cos(angle), sin(angle))
                self.id = nom
                self.maitre = maitre
                self.surface = surface
        def update(self):
                "Mise à jour du tir"
                global width, height
                i = 0
                while i < self.speed:
                        self.pos = (self.pos[0] + self.move[0], self.pos[1] + self.move[1])
                        if 0 >= self.pos[0] >= width or 0 >= self.pos[1] >= height:
                                self.maitre.delete(self.id)
                        i += 1
                
                pygame.draw.circle(self.surface, self.maitre.colors[4], self.pos, self.rayon)
                pygame.draw.circle(self.surface, self.maitre.colors[1], self.pos, self.rayon, 1)

class Ennemi():
        "Classe de l'ennemi"
        speed = 3
        def __init__(self, pos, vie, ennemi, nom, groupe, surface):
                self.pos = pos
                self.angle = 0
                self.vie = vie
                self.ennemi = ennemi
                self.id = nom
                self.groupe = groupe
                self.surface =  surface
                
        def update(self):
                global ennemi
		#Calcul du nouvel angle de la rotation
                angle = atan2(self.ennemi.pos[1] - self.pos[1], self.ennemi.pos[0] - self.pos[0])
                self.pos = (self.pos[0] + cos(angle) * self.speed, self.pos[1] + sin(angle) * self.speed)

                self.angle += pi / 18

                if self.angle >= 2 * pi:
                        self.angle = self.angle - 2 * pi
		
		#Gestion des collisions avec nos tirs
                for i in self.ennemi.tirs:
                        if self.pos[0] - 5 * self.vie <= i.pos[0] <= self.pos[0] + 5 * self.vie and\
                           self.pos[1] - 5 * self.vie <= i.pos[1] <= self.pos[1] + 5 * self.vie:
                                self.vie -= 1
                                i.maitre.delete(i.id)
		
		#Gestion des collisions avec le joueur
                if self.pos[0] - 5 * self.vie <= self.ennemi.pos[0] <= self.pos[0] + 5 * self.vie and\
                   self.pos[1] - 5 * self.vie <= self.ennemi.pos[1] <= self.pos[1] + 5 * self.vie:
                        self.ennemi.vie -= 1
                        self.groupe.delete(self.id, 0)
			
                #Mort de l'ennemi
                if self.vie <= 0:
                        self.groupe.delete(self.id, 100)
                
		#Dessin de l'ennemi
                pygame.draw.polygon(self.surface, ennemi[0], [
                        (self.pos[0] + cos(self.angle) * self.vie * 5, self.pos[1] + sin(self.angle) * self.vie * 5),
                        (self.pos[0] + cos(self.angle + pi/2) * self.vie / 2 * 5, self.pos[1] + sin(self.angle + pi/2) * self.vie / 2 * 5),
                        (self.pos[0] + cos(self.angle + pi) * self.vie * 5, self.pos[1] + sin(self.angle + pi) * self.vie * 5),
                        (self.pos[0] + cos(self.angle - pi/2) * self.vie / 2 * 5, self.pos[1] + sin(self.angle - pi/2) * self.vie / 2 * 5)])

                pygame.draw.polygon(self.surface, ennemi[1], [
                        (self.pos[0] + cos(self.angle) * self.vie * 5, self.pos[1] + sin(self.angle) * self.vie * 5),
                        (self.pos[0] + cos(self.angle + pi/2) * self.vie / 2 * 5, self.pos[1] + sin(self.angle + pi/2) * self.vie / 2 * 5),
                        (self.pos[0] + cos(self.angle + pi) * self.vie * 5, self.pos[1] + sin(self.angle + pi) * self.vie * 5),
                        (self.pos[0] + cos(self.angle - pi/2) * self.vie / 2 * 5, self.pos[1] + sin(self.angle - pi/2) * self.vie / 2 * 5)], 3)
                   
class Controlleur():
        "Controle les ennemis"
        unites = []
        score = 0
        temps = 0
        def __init__(self,ennemi, surface):
                self.ennemi = ennemi
                self.surface = surface

        def update(self):
                global width, height, infos
                if not randrange(0, 50):
                        x = randrange(0, 2)
                        if x:
                                x *= width
                                y = randrange(0, 2) * height
                        else:
                                y = randrange(0, height)
                                x = randrange(0, 2) * width
                        self.unites.append(Ennemi((x, y), randrange(0, 11), self.ennemi, len(self.unites), self, self.surface))

                for i in self.unites:
                        i.update()

                self.temps += 1
                
                score = pygame.font.Font("freesansbold.ttf", 20).render("score: "+str(self.score)+" temps:"+str(self.temps), 1, infos[2])
                scorect = score.get_rect()
                scorect.left = 10
                scorect.top = 10

                cadre = Rect(0, 0, scorect.width + 20, scorect.height + 20)

                pygame.draw.rect(self.surface, infos[0], cadre)
                pygame.draw.rect(self.surface, infos[1], cadre, 3)

                self.surface.blit(score, scorect)

        def delete(self, nom, add):
                "Efface l'ennemi"
                self.unites[nom:nom+1] = []
                i = nom
                while i < len(self.unites):
                        self.unites[i].id = i
                        i += 1
                self.score += add

class Curseur():
        "Classe du curseur"
        def __init__(self, surface):
                pygame.mouse.set_visible(0)
                self.surface = surface
        def update(self):
                pygame.draw.circle(self.surface, (255, 255, 255), pygame.mouse.get_pos(), 5, 1)

#Jeu
ecran = pygame.display.set_mode(size)
pygame.display.set_caption("VIRTUAL SHOOTING")
pygame.key.set_repeat()

curseur = Curseur(ecran)

while 1:
        intro(ecran)
        jeu(ecran, curseur)

Conclusion :


Si jamais vous trouvez un bug, que vous trouvez que je n'ai pas assez commenté (les commentaires c'est pa smon fort >_<), ou que vous pensez à des améliorations, n'hésitez pas à me le faire savoir.

Codes Sources

A voir également

Ajouter un commentaire

Commentaire

theoChey
Messages postés
2
Date d'inscription
samedi 15 octobre 2011
Statut
Membre
Dernière intervention
15 octobre 2011
-
c'est bizarre, Python me met: "No module named pygame" ...

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.